TextView一次性设置自定义字体-在res/font里的办法
- 一般设置自定义字体的办法
- 我遇到的实际情况
- 工友总是跑的很‘快’
- 没法使用的第二种方式(将font放在asset下)
- 本民工最终的解决办法,干净利落!
- 死磕过程中遇到的难题
一般设置自定义字体的办法
一般有两种方式:
1,将font文件放在res/font/目录下,然后在布局xml中这样写:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/my_fonts"
这样缺点很明显,每个需要的TextView都要在xml里加上这样的属性。工程大了维护起来太恐怖。而且这样也非常不软件工程,于是网上有第二种办法。
2,将font文件放在assets/fonts/目录下,然后自定义MyFontTextView继承TextView,并统一设置字体:
public class MyFontTextView extends android.support.v7.widget.AppCompatTextView {
public MyFontTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
Typeface typeFace = Typeface.createFromAsset(context.getAssets(), "fonts/my_fonts.ttf");
setTypeface(typeFace);
}
这种方法一般比较适用,大多数工友能这样做就OK了。但是。。。
我遇到的实际情况
上面两个办法,足够一般项目应用了。
- 如果是少量地方要自定义字体,用第一种办法。
- 如果是大范围的TextView要用自定义字体,用第二种办法
但作为android搬砖民工,总是遇得到坑坑的事情。【捂脸】
工友总是跑的很‘快’
我们项目要求UI改变,所有字体几乎都要替换成一个自定义的font。
但工友直接用第一个方式,每个TextView的xml添加一个android:fontFamily属性,简直不要太酸爽。实在是佩服工友任劳任怨,一匹一匹砖慢慢搬的民工精神。
可是!本民工擅长偷懒,绝对不干这种重复劳动!绝对不能面向CV搬砖!
开干!
没法使用的第二种方式(将font放在asset下)
如果要用第二种方式一劳永逸是很简单。但我们font文件大小是10MB数量级。把font文件copy一份放到asset下会让APK包体积有增大对应的size,简直不能忍。
而且因为工友已经大范围Copy + Paste 修改,也不可能改回去。
本民工最终的解决办法,干净利落!
以第二种方式一劳永逸,但保持font文件在res/font目录下的办法,死磕一下午终于研究出来!直接上代码!拿来就能用!
1,在res/values/styles.xml里创建如下style样式:
<style name="font_my_new">
<item name="android:fontFamily">@font/my_font</item>
</style>
2,NewFontTextView extends TextView,并初始化时如下应用该样式,即可应用对应字体:
public NewFontTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
setTextAppearance(R.style.my_fonts);
} else {
setTextAppearance(context, R.style.my_fonts);
}
死磕过程中遇到的难题
1,一开始试想,参考第二种asset/font的方法,把res/font下的字体文件获取到,然后通过setTypeface(typeFace)的方式设置。这里查看了Typeface的对应方法,发现相关的create方法都没法通过res/font目录下的文件创建出Typeface。
其中有两个方法createFromFile(String path)我一开始还报以希望,结果没找到获取res/font对应文件的办法。
2,找到一个这样的办法:
Typeface tf = context.getResources().getFont(R.font.hyqh_40s);
setTypeface(tf);
但很可惜context.getResources().getFont这个方法要求兼容的mini SDK level至少26。现在估计大多数APP的mini SDK 还是16吧。
3,最后研究TextView的源码,根据font_family参数,找到了上面的解决办法。