情景:需要为整个应用替换自定义字体。
Android对于文字的字体设置主要是通过以下两个对象
FontFamily、Typeface
在XML文件中设置单个字体:
android:id="@+id/tv_typeface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:fontFamily="sans-serif-condensed"
android:text="@string/custom_typeface" />
代码中设置单个字体:
TextView tvTypeface = (TextView) findViewById(R.id.tv_typeface);
tvTypeface.setTypeface(Typeface.create("sans-serif-condensed",Typeface.NORMAL));
看到这儿,可能会有人有疑问,这里边设置的“sans-serif-condensed”从哪儿来的。有什么系统可以设置的字体呢?如果要自定义字体怎么设置?
首先我们先来看下系统内置的字体都有哪些?
/system/etc/fonts.xml
可以看到这个配置文件详细定义了具体的fontFamily名称及对应的字体文件,而我们设置的系统支持的字体就来源于这个文件,在不同的A你droid版本的系统内置的系统字体是不一样的
...
Roboto-Thin.ttf
Roboto-ThinItalic.ttf
Roboto-Light.ttf
Roboto-LightItalic.ttf
Roboto-Regular.ttf
Roboto-Italic.ttf
Roboto-Medium.ttf
Roboto-MediumItalic.ttf
Roboto-Black.ttf
Roboto-BlackItalic.ttf
Roboto-Bold.ttf
Roboto-BoldItalic.ttf
NotoSerif-Regular.ttf
NotoSerif-Bold.ttf
NotoSerif-Italic.ttf
NotoSerif-BoldItalic.ttf
DroidSansMono.ttf
CutiveMono.ttf
ComingSoon.ttf
...
/system/fonts
这个文件夹里边存储了系统具体的字体文件
AndroidClock.ttf
AndroidClock_Highlight.ttf
AndroidClock_Solid.ttf
AndroidEmoji.ttf
Clockopia.ttf
DroidNaskh-Regular.ttf
DroidNaskhUI-Regular.ttf
DroidSans-Bold.ttf
DroidSans.ttf
DroidSansArmenian.ttf
DroidSansEthiopic-Regular.ttf
DroidSansFallback.ttf
DroidSansGeorgian.ttf
DroidSansHebrew-Bold.ttf
DroidSansHebrew-Regular.ttf
DroidSansMono.ttf
DroidSerif-Bold.ttf
DroidSerif-BoldItalic.ttf
DroidSerif-Italic.ttf
DroidSerif-Regular.ttf
MTLmr3m.ttf
Roboto-Bold.ttf
Roboto-BoldItalic.ttf
Roboto-Italic.ttf
Roboto-Light.ttf
Roboto-LightItalic.ttf
Roboto-Regular.ttf
Roboto-Thin.ttf
...
设置自定义字体文件
新建/res/font 文件夹,添加自定义的字体文件 .ttf或者.otf,如添加typeface_bold.ttf自定义字体文件,
android:id="@+id/tv_typeface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:fontFamily="@font/typeface_bold"
android:text="@string/custom_typeface" />
Typeface.create(ResourcesCompat.getFont(context, R.font.typeface_bold), Typeface.NORMAL);
SpannableString设置自定义字体
/**
* 自定义TypefaceSpan
*/
public class CustomTypefaceSpan extends TypefaceSpan {
private final Typeface newType;
public CustomTypefaceSpan(String family, Typeface type) {
super(family);
newType = type;
}
@Override
public void updateDrawState(TextPaint ds) {
applyCustomTypeFace(ds, newType);
}
@Override
public void updateMeasureState(TextPaint paint) {
applyCustomTypeFace(paint, newType);
}
private static void applyCustomTypeFace(Paint paint, Typeface tf) {
paint.setTypeface(tf);
}
//设置自定义的TypefaceSpan
setSpan(new CustomTypefaceSpan(text.toString(), typeFace), start, end, flag);
如何为整个APP,全局替换字体呢?
添加自定义字体到Application的theme
casual
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/FontStyle">
android:name=".CustomTypefaceActivity"
android:theme="@style/FontStyle" />
为不同的语言设置不同的字体
资源文件下面添加自定义字体文件
/res/font/ibmplexsans_semibold.ttf
/res/font/sarabun_semibold.ttf
资源文件夹下面创建不同语言的theme 不同theme定义不同的字体引用
@font/ibmplexsans_semibold
@font/sarabun_semibold
代码创建工具类不同语言引用不同的字体
public class FontUtil {
public static Typeface createTypeFace(Context context, @FontConstant.FontTemplete String font) {
int fontResourceId = R.font.sarabun_regular;
if (LanguageManager.getInstance(context).isCurrentThai()) {
if (FontConstant.FONT_BOLD.equalsIgnoreCase(font)) {
fontResourceId = R.font.sarabun_bold;
}...
} else {
if (FontConstant.FONT_BOLD.equalsIgnoreCase(font)) {
fontResourceId = R.font.ibmplexsans_bold;
}...
}
return Typeface.create(ResourcesCompat.getFont(context, fontResourceId), Typeface.NORMAL);
}
}
还有一种根据不同语言定义不同字体的方法,但是这种在语言切换后定义的不同字体需要APP杀死重启才会生效
/res/fonts/ibmplexsans_semibold.ttf
/res/fonts-th-rTH/ibmplexsans_semibold.ttf //名称需要同默认字体一样 但是实际是泰文字体