Android字体占有内存,Android 性能优化:字体 (为自定义字体提供字体内存缓存)

Android 上自定义字体的代码一般如下:

TextView textview =(TextView) findViewById(R.id.your_referenced_textview);//adjust this line to get the TextView you want to change

Typeface typeface= Typeface.createFromAsset(getAssets(),"SourceSansPro-Regular.ttf"); //create a typeface from the raw ttf

textview.setTypeface(typeface); //apply the typeface to the textview

然后就结束了,如果想要改变一个Textview的字体就是这么简单,最好的情况就是上面的代码在 onCreate() 方法中进行调用。

如果你只想用在单个实例上那么这种方法是足够的,但是如果你想要给app中成千上万的view都使用自定义字体的话,这可能就不是一个好方法了,毕竟我们不可能在每个初始化的地方都去加上上面那一段

提供字体内存缓存

虽然Android现在已经很流畅,但是我们依然应该考虑优化性能。所以,我们应该把自定义的字体缓存起来,这样就不用每次去初始化,在 britzl on stackoverflow上有一个比较好的答案。

public classFontCache {private static HashMap fontCache = new HashMap<>();public staticTypeface getTypeface(String fontname, Context context) {

Typeface typeface=fontCache.get(fontname);if (typeface == null) {try{

typeface=Typeface.createFromAsset(context.getAssets(), fontname);

}catch(Exception e) {return null;

}

fontCache.put(fontname, typeface);

}returntypeface;

}

}

缓存下字体就能让我们不用一直去操作 Assets 文件夹,接下来就能实现一个继承自 TextView 的类。

继承TextView

首先来创建一个类继承自 TextView,这样就能在 XML 中来使用,它继承了 TextView所有的属性和功能,然后再加上自定义的字体。

public class EatFoodyTextView extendsTextView {publicEatFoodyTextView(Context context) {super(context);

applyCustomFont(context);

}publicEatFoodyTextView(Context context, AttributeSet attrs) {super(context, attrs);

applyCustomFont(context);

}public EatFoodyTextView(Context context, AttributeSet attrs, intdefStyle) {super(context, attrs, defStyle);

applyCustomFont(context);

}private voidapplyCustomFont(Context context) {

Typeface customFont= FontCache.getTypeface("SourceSansPro-Regular.ttf", context);

setTypeface(customFont);

}

}

开始的三个都是构造函数,里面都调用了 applyCustomFont() 方法,然后从上面的 FontCache 类中拿到缓存的字体文件,这样就不用每个view都去重复的从 Assets中取字体,节约了资源,最后将取到的字体设置到 setTypeface() 中。

使用自定义类

现在我们只需要在XML中直接使用,不需要再写其他的java代码,

android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/eat_foody_green_dark"android:textSize="20sp"android:text="Future Studio Blog"android:layout_marginBottom="24dp"/>

我们可以依然使用TextView的其他属性,(textSize,textColor之类的),只需要把 替换成 ,这个前面的是全部的包名,然后就会自己应用字体。

但是使用中会发现,虽然一些TextView的属性比如 textSize 能正常的显示,但是 textStyle 这个属性并不能正常的生效。

添加每个ttf文件

首先将同一个系列的三种样式的 ttf 文件都加到 assets 中

8f2150656c6414b7c2ccf5a1d434a2eb.png

在XML中使用textStyle属性

在前面已经讲解了自定义view的使用

android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="12dp"android:text="http://futurestud.io/blog/"android:textSize="18sp"android:textStyle="bold"/>

一般情况下,我们更希望使用的是标准的 android:textStyle 而不是用一个自定义的属性 customfont:textStyle 。但是像上面这样的属性直接放上去肯定是不能生效的,还需要再加一些代码才行。

提示:如果你对使用 customfont:textStyle 的方式比较感兴趣,那么下一篇文章中会介绍如何使用。

实现CustomFontTextView

为了能继续的使用系统的 android:textStyle 属性,需要一些步骤。

首先需要在代码拿到这个属性的信息,这只需要一行代码:

int textStyle = attrs.getAttributeIntValue(ANDROID_SCHEMA, "textStyle", Typeface.NORMAL);

attr 这个值是来自 TextView 的第二个构造函数中的参数,我们可以使用这个对象的 getAttributeIntValue() 方法获取XML的属性。

先看一下上面代码中的 ANDROID_SCHEMA 这个参数,这个是一个常量,定义在XML的最顶部中(xmlns:android="http://schemas.android.com/apk/res/android" ),第二个参数就是定义的属性名,最后一个参数是默认值,如果这个属性没有设置,那么就会选择 Typeface.NORMAL。

当我们考虑了样式之后,完善一下代码,全部的代码看起来就像下面这样。

public class CustomFontTextView extendsTextView {public static final String ANDROID_SCHEMA = "http://schemas.android.com/apk/res/android";publicCustomFontTextView(Context context, AttributeSet attrs) {super(context, attrs);

applyCustomFont(context, attrs);

}public CustomFontTextView(Context context, AttributeSet attrs, intdefStyle) {super(context, attrs, defStyle);

applyCustomFont(context, attrs);

}private voidapplyCustomFont(Context context, AttributeSet attrs) {int textStyle = attrs.getAttributeIntValue(ANDROID_SCHEMA, "textStyle", Typeface.NORMAL);

Typeface customFont=selectTypeface(context, textStyle);

setTypeface(customFont);

}private Typeface selectTypeface(Context context, inttextStyle) {/** information about the TextView textStyle:

*http://developer.android.com/reference/android/R.styleable.html#TextView_textStyle*/

switch(textStyle) {case Typeface.BOLD: //bold

return FontCache.getTypeface("SourceSansPro-Bold.ttf", context);case Typeface.ITALIC: //italic

return FontCache.getTypeface("SourceSansPro-Italic.ttf", context);case Typeface.BOLD_ITALIC: //bold italic

return FontCache.getTypeface("SourceSansPro-BoldItalic.ttf", context);case Typeface.NORMAL: //regular

default:return FontCache.getTypeface("SourceSansPro-Regular.ttf", context);

}

}

这样我们的自定义字体就能使用标准的应用字体样式 textStyle。

看看成果

首先我们在XML中写一些布局,包括原生的 Roboto 字体以及不同形式的自定义字体。

android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="12dp"android:text="http://futurestud.io/blog/"android:textSize="18sp"/>

android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="12dp"android:text="http://futurestud.io/blog/"android:textSize="18sp"android:textStyle="bold"/>

android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_margin="12dp"android:text="http://futurestud.io/blog/"android:textSize="18sp"android:textStyle="italic"/>

这个文件在模拟器上显示的效果就像下面这样。

9428737466bc54a1e503b50742057c14.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值