情景:需要为整个应用替换自定义字体。
Android对于文字的字体设置主要是通过以下两个对象
FontFamily、Typeface
- 在XML文件中设置单个字体:
<TextView
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版本的系统内置的系统字体是不一样的
...
<family name="sans-serif">
<font weight="100" style="normal">Roboto-Thin.ttf</font>
<font weight="100" style="italic">Roboto-ThinItalic.ttf</font>
<font weight="300" style="normal">Roboto-Light.ttf</font>
<font weight="300" style="italic">Roboto-LightItalic.ttf</font>
<font weight="400" style="normal">Roboto-Regular.ttf</font>
<font weight="400" style="italic">Roboto-Italic.ttf</font>
<font weight="500" style="normal">Roboto-Medium.ttf</font>
<font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
<font weight="900" style="normal">Roboto-Black.ttf</font>
<font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
<font weight="700" style="normal">Roboto-Bold.ttf</font>
<font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
</family>
<family name="serif">
<font weight="400" style="normal">NotoSerif-Regular.ttf</font>
<font weight="700" style="normal">NotoSerif-Bold.ttf</font>
<font weight="400" style="italic">NotoSerif-Italic.ttf</font>
<font weight="700" style="italic">NotoSerif-BoldItalic.ttf</font>
</family>
<family name="monospace">
<font weight="400" style="normal">DroidSansMono.ttf</font>
</family>
<alias name="sans-serif-monospace" to="monospace" />
<alias name="monaco" to="monospace" />
<family name="serif-monospace">
<font weight="400" style="normal">CutiveMono.ttf</font>
</family>
<alias name="courier" to="serif-monospace" />
<alias name="courier new" to="serif-monospace" />
<family name="casual">
<font weight="400" style="normal">ComingSoon.ttf</font>
</family>
...
/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自定义字体文件,
<!--XML设置自定义字体-->
<TextView
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
<style name="FontStyle">
<item name="android:fontFamily">casual</item>
</style>
<!--修改AndroidManifest文件Application style属性即可-->
<application
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">
</application>
<!--单独修改Activity样式-->
<activity
android:name=".CustomTypefaceActivity"
android:theme="@style/FontStyle" />
为不同的语言设置不同的字体
- 资源文件下面添加自定义字体文件
<!-- 默认全局中粗字体 -->
/res/font/ibmplexsans_semibold.ttf
<!-- 泰文中粗字体 -->
/res/font/sarabun_semibold.ttf
- 资源文件夹下面创建不同语言的theme 不同theme定义不同的字体引用
<!-- /res/values/styles.xml -->
<style name="TextViewFontSemiBold">
<item name="android:fontFamily">@font/ibmplexsans_semibold</item>
</style>
<!-- /res/values-th-rTH/styles.xml -->
<style name="TextViewFontSemiBold">
<item name="android:fontFamily">@font/sarabun_semibold</item>
</style>
- 代码创建工具类不同语言引用不同的字体
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 //名称需要同默认字体一样 但是实际是泰文字体
网友评论