版權(quán)說明:本文為 開開向前沖 原創(chuàng)文章,轉(zhuǎn)載請注明出處;
注:限于作者水平有限,文中有不對的地方還請指教
背景: 最近在做一個(gè)智能POS項(xiàng)目,Android 平臺:L,系統(tǒng)需要的字庫Android 默認(rèn)沒有,需要添加到系統(tǒng);
我們平時(shí)開發(fā)中,很少去使用特定的字體,但是字體卻存在于我們系統(tǒng)中,如何針對特定的文本指定特定的字庫呢?
public class MainActivity extends AppCompatActivity {
TextView textView1;
TextView textView2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);//activity_main.xml 里面只有兩個(gè)TextView,ID為tx1,tx2;
textView1 = (TextView) findViewById(R.id.tx1));
textView2 = (TextView) findViewById(R.id.tx2));
textView1.setText("Hello World");
textView2.setText("Hello World");
textView1.setTypeface(Typeface.create("AvenirNextCondensed",Typeface.NORMAL));//AvenirNextCondensed是我添加的字庫
textView2.setTypeface(Typeface.create("simkai",Typeface.NORMAL));
}
}
activity_main.xml很簡單,篇幅原因就不貼代碼了;
對,你沒看錯(cuò),字體的設(shè)置就是這么簡單,控件可以直接使用,和使用setText()方法的使用一樣;對于這個(gè)字庫是如何添加呢?我剛接到任務(wù)時(shí)也不清楚,Google 了一下,在Stack Overflow 上找到一篇android-add-custom-fonts-to-system;正常這篇文章主要是講解如何將字庫文件(.ttf)編譯到/system/fonts目錄,還需要參考系統(tǒng)字庫的配置方式修改
/frameworks/base/data/fonts/system_fonts.xml
/frameworks/base/data/fonts/fallback_fonts.xml
/frameworks/base/data/fonts/fonts.xml
但是當(dāng)我根據(jù)文章把一切配置OK后,編寫上面測試程序,發(fā)現(xiàn)竟然無效;因?yàn)?a target="_blank" rel="nofollow">android-add-custom-fonts-to-system文章中少配置了一個(gè)文件; frameworks/base/data/fonts/fonts.xml
這里我說一下添加字庫到系統(tǒng)的完整步驟:
1:Copy 自己添加的字體庫文件(后綴是.ttf)到目錄 frameworks/base/data/fonts
2:Modify framworks/base/data/fonts/Android.mk
3:Modify frameworks/base/data/fonts/fonts.mk
4:Modify frameworks/base/data/fonts/system_fonts.xml
5:Modify frameworks/base/data/fonts/fallback_fonts.xml
6:Modify frameworks/base/data/fonts/fonts.xml
步驟一:
拷貝文件這個(gè)很簡單,不需要細(xì)說,記住需要到的目錄就好;
步驟二:
Modify framworks/base/data/fonts/Android.mk
在font_src_files 中添加需要編譯的字體庫名字:
font_src_files := \
Roboto-Regular.ttf \
Roboto-Bold.ttf \
...
simsun.ttc \
simkai.ttf \
msyh.ttf \
impact-Regular.ttf \
AvenirNextCondensed-Bold.ttf \
PosSong-8.ttf \
PosSong-16.ttf \
PosSong-24.ttf \
simfang.ttf
步驟三:
Modify frameworks/base/data/fonts/fonts.mk
在PRODUCT_PACKAGES下添加需要編譯的字體庫名字:
PRODUCT_PACKAGES := \
DroidSansFallback.ttf \
Roboto-Regular.ttf \
......
simsun.ttc \
simkai.ttf \
msyh.ttf \
impact-Regular.ttf \
AvenirNextCondensed-Bold.ttf \
PosSong-8.ttf \
PosSong-16.ttf \
PosSong-24.ttf \
simfang.ttf
步驟四:
Modify frameworks/base/data/fonts/system_fonts.xml
下面對應(yīng)用使用應(yīng)用內(nèi)部Assets資源與調(diào)用系統(tǒng)的字體庫方式進(jìn)行比較:
textView1.setTypeface(Typeface.create("simkai",Typeface.NORMAL));//調(diào)用系統(tǒng)
textView1.setTypeface(Typeface.createFromAsset(this.getAssets(),"simkai.ttf"));//調(diào)用應(yīng)用內(nèi)部Assets資源
從上面代碼差異我們就知道,調(diào)用系統(tǒng)的時(shí)候不需要使用具體執(zhí)行一個(gè)具體的ttf(simkai.ttf)庫文件,但是需要指定一個(gè)具體的名字("simkai"),其實(shí)這個(gè)名字就是("simkai")就是指向了simkai.ttf 文件,那這個(gè)名字和具體的字體庫文件是如何關(guān)聯(lián)的嗎(看著就像把字體庫的全名(simkai.ttf)去掉.ttf的后綴得到的(simkai))?那具體是不是這樣呢?答案是否定的,只是我們習(xí)慣的配置方式是這樣配置而已,至于具體的配置在那里呢?
frameworks/base/data/fonts/system_fonts.xml
在該文件中添加字體庫的nameset和fileset對應(yīng)關(guān)系;
<family>
<nameset>
<name>simkai</name>
</nameset>
<fileset>
<file>simkai.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>AvenirNextCondensed</name>
</nameset>
<fileset>
<file>AvenirNextCondensed-Bold.ttf</file>
</fileset>
</family>
看到?jīng)],這里simkai的nameset指向了simkai.ttf的fileset。你也可以根據(jù)你自己的名字來命名;
步驟5:
Modify frameworks/base/data/fonts/fallback_fonts.xml
在該文件中添加字體庫文件的fileset
<family>
<fileset>
<file>simkai.ttf</file>
</fileset>
</family>
<!-- add for msyh-->
<family>
<fileset>
<file>msyh.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>impact-Regular.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>AvenirNextCondensed-Bold.ttf</file>
</fileset>
</family>
步驟6:
Modify frameworks/base/data/fonts/fonts.xml
配置系統(tǒng)庫字體,在Android 5.1中必須配置,相同字體庫文件的 family name 必須和和前面system_fonts.xml文件中的nameset一致(理論上一致,有興趣的讀者可以嘗試不一致,我沒有試過),textView1.setTypeface(Typeface.create("simkai",Typeface.NORMAL));
<family name="simkai">
<font weight="400" style="normal">simkai.ttf</font>
</family>
<family name="msyh">
<font weight="400" style="normal">msyh.ttf</font>
</family>
<family name="impact">
<font weight="400" style="normal">impact-Regular.ttf</font>
</family>
<family name="simfang">
<font weight="400" style="normal">simfang.ttf</font>
</family>
<family name="AvenirNextCondensed">
<font weight="400" style="normal">AvenirNextCondensed-Bold.ttf</font>
</family>
特別注意:我們修改了這幾個(gè)文件還需要注意一些編譯細(xì)節(jié),比如上述幾個(gè).xml文件都會(huì)被編譯到/system/etc/目錄下,但是我在Android 5.1 中編譯了卻有一個(gè)文件沒有生效,那就是fonts.xml,經(jīng)過比較,我發(fā)現(xiàn)系統(tǒng)中的fonts.xml沒有我添加的內(nèi)容,經(jīng)過在系統(tǒng)中查找,發(fā)現(xiàn)了貓膩:
vendor/qcom/proprietary/qrdplus/globalization/engine目錄下的Android.mk文件中有如下語句:
include $(CLEAR_VARS)
LOCAL_MODULE := fonts.xml
LOCAL_SRC_FILES := fonts-Rev.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/etc
include $(BUILD_PREBUILT)
上面這個(gè)代碼的意思是把fonts-Rev.xml 編譯到編譯成fonts.xml,拷貝到/system/etc目錄下;看到這里就知道為什么我的修改沒生效了吧;我的修改先編譯到/system/etc目錄下,然后被這個(gè)fonts-Rev.xml編譯的fonts.xml覆蓋了(經(jīng)過對比發(fā)現(xiàn)編譯出來的/system/etc/fonts.xml果真和這個(gè)fonts-Rev.xml一模一樣);兩種解決辦法:1,將我的修改添加到vendor/qcom/proprietary/qrdplus/globalization/engine目錄下的fonts-Rev.xml;2,在vendor/qcom/proprietary/qrdplus/globalization/engine的Android.mk中將上面的那幾行代碼注釋掉;