1. 在xml中指定字体。
2. 通过重写TextView来设置字体。(吃内存怪兽1)
3. 在Activity的初始化阶段为每一个TextView设置字体。(吃内存怪兽2)
最近遇到一个需求,需要在程序中应用很多套字体。(中英各三种),所以想寻求一条简单的方式来实现。
在网上搜索了很久,看起来Android并不支持直接指定FontFamily来设置字体,真坑!!(思路:Root -> 复制字体到system/Fonts文件夹里,然后再在程序中指定对应的FontFamily)未测试~~囧~~
网上几个主流的做法是重写TextView,以此来达到重写文本的目的。我暂时采用的就是这种方式。(这个方式有个致命缺点,狂占内存)
通过继承TextView来实现诸如TitleTextView、ContentTextView、RemarkTextView之类的自定义字体控件。为每一个自定义控件指定一种字体。
例如TitleTextView:
public class TitleTextView extends TextView {
public TitleTextView(Context context) {
this(context, null);
}
public TitleTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TitleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setTypeface(Typeface.createFromAsset(getResources().getAssets(), "zhongteyuanti.ttc"));
}
}
通过这种方式一个好处是,不需要为每一个TextView指定它的FontFamily,每一个类即有自己的Font属性。
xml中的用法为:
<com.Yokeqi.Controls.TitleTextView
android:id="@+id/tv_login_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="@string/login_title" />
这个TextView显示出来即是zhongteyuanti这一种字体了。
----------------- 这一段是总结,不采用这种方式的please跳过 -----------------
对这种方式,感触比较深的是它吃内存的能力~~!!我一个不指定字体57MB的程序,用这种方式指定字体后居然是440+MB,所以需要优化啦没得说。
由此衍生出config的想法:Key-Value分别是FontFamily-Typeface。再由一个FontManager来管理这个config(概念),利用单例模式限定每个FontFamily只会拿到同一个Typeface实例,大大降低创建Typeface的内存损耗,哈哈。
我的FontManager中添加了getTypefaceByFontName(Context context, String name)的方法。
public static HashMap<String, Typeface> TypefaceMap = new HashMap<String, Typeface>();
public static Typeface getTypefaceByFontName(Context context,String name){
if (TypefaceMap.containsKey(name)) {
return TypefaceMap.get(name);
} else {
Typeface tf = Typeface.createFromAsset(context.getResources().getAssets(), name);
TypefaceMap.put(name, tf);
return tf;
}
}
TtitleTextView中设置字体的代码则可以改为:
this.setTypeface(FontManager.getTypefaceByFontname("zhongteyuanti.ttc"));
扩展思路部分:
另外我的config还有语言选项,因为程序需要根据中英两种语言来取不同的字体的。
最后,config变成了一个xml,存放于Assets中,这样万一修改FontFamily对应的字体的时候就简单多了。
同时key-value变成了FontFamily-FontFileName,FontManager就负责解析这个config来得到FontFamily对应Assets中的字体文件名,然后再获取Typeface。
================== 最后一种方式 ===================
在Activity的初始化阶段来指定字体,因为程序中我不光TextView需要自定义字体,Button、Spinner也需要自定义字体,肿么办??!!
我只能想到添加一个initFont()的方法到初始化吧,相关的控件也其实不多,写多点代码总比没办法实现好~~(你真的有好办法??)
这个方法也是指定Typeface,所以这个方法也是吃内存怪兽型,一样要考虑下采用单例模式的思想来获取Typeface。否则你TMD在逗我。