情景:需要為整個應(yīng)用替換自定義字體。
Android對于文字的字體設(shè)置主要是通過以下兩個對象
FontFamily、Typeface
- 在XML文件中設(shè)置單個字體:
<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" />
- 代碼中設(shè)置單個字體:
TextView tvTypeface = (TextView) findViewById(R.id.tv_typeface);
tvTypeface.setTypeface(Typeface.create("sans-serif-condensed",Typeface.NORMAL));
看到這兒,可能會有人有疑問,這里邊設(shè)置的“sans-serif-condensed”從哪兒來的。有什么系統(tǒng)可以設(shè)置的字體呢?如果要自定義字體怎么設(shè)置?
首先我們先來看下系統(tǒng)內(nèi)置的字體都有哪些?
/system/etc/fonts.xml
可以看到這個配置文件詳細定義了具體的fontFamily名稱及對應(yīng)的字體文件,而我們設(shè)置的系統(tǒng)支持的字體就來源于這個文件,在不同的A你droid版本的系統(tǒng)內(nèi)置的系統(tǒng)字體是不一樣的
...
<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
這個文件夾里邊存儲了系統(tǒng)具體的字體文件
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
...
- 設(shè)置自定義字體文件
新建/res/font 文件夾,添加自定義的字體文件 .ttf或者.otf,如添加typeface_bold.ttf自定義字體文件,
<!--XML設(shè)置自定義字體-->
<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" />
<!--代碼設(shè)置自定義字體-->
Typeface.create(ResourcesCompat.getFont(context, R.font.typeface_bold), Typeface.NORMAL);
SpannableString設(shè)置自定義字體
/**
* 自定義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);
}
//設(shè)置自定義的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" />
為不同的語言設(shè)置不同的字體
- 資源文件下面添加自定義字體文件
<!-- 默認全局中粗字體 -->
/res/font/ibmplexsans_semibold.ttf
<!-- 泰文中粗字體 -->
/res/font/sarabun_semibold.ttf
- 資源文件夾下面創(chuàng)建不同語言的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>
- 代碼創(chuàng)建工具類不同語言引用不同的字體
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);
}
}
- 還有一種根據(jù)不同語言定義不同字體的方法,但是這種在語言切換后定義的不同字體需要APP殺死重啟才會生效
/res/fonts/ibmplexsans_semibold.ttf
/res/fonts-th-rTH/ibmplexsans_semibold.ttf //名稱需要同默認字體一樣 但是實際是泰文字體