美文网首页
Android 添加字体库到系统

Android 添加字体库到系统

作者: 开开向前冲 | 来源:发表于2017-08-21 15:47 被阅读0次

    版权说明:本文为 开开向前冲 原创文章,转载请注明出处;
    注:限于作者水平有限,文中有不对的地方还请指教

    背景: 最近在做一个智能POS项目,Android 平台:L,系统需要的字库Android 默认没有,需要添加到系统;

    我们平时开发中,很少去使用特定的字体,但是字体却存在于我们系统中,如何针对特定的文本指定特定的字库呢?

    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 里面只有两个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很简单,篇幅原因就不贴代码了;
    对,你没看错,字体的设置就是这么简单,控件可以直接使用,和使用setText()方法的使用一样;对于这个字库是如何添加呢?我刚接到任务时也不清楚,Google 了一下,在Stack Overflow 上找到一篇android-add-custom-fonts-to-system;正常这篇文章主要是讲解如何将字库文件(.ttf)编译到/system/fonts目录,还需要参考系统字库的配置方式修改

    /frameworks/base/data/fonts/system_fonts.xml
    /frameworks/base/data/fonts/fallback_fonts.xml
    /frameworks/base/data/fonts/fonts.xml

    但是当我根据文章把一切配置OK后,编写上面测试程序,发现竟然无效;因为android-add-custom-fonts-to-system文章中少配置了一个文件; frameworks/base/data/fonts/fonts.xml

    这里我说一下添加字库到系统的完整步骤:

    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

    步骤一:

    拷贝文件这个很简单,不需要细说,记住需要到的目录就好;

    步骤二:

    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
    下面对应用使用应用内部Assets资源与调用系统的字体库方式进行比较:

    textView1.setTypeface(Typeface.create("simkai",Typeface.NORMAL));//调用系统
    textView1.setTypeface(Typeface.createFromAsset(this.getAssets(),"simkai.ttf"));//调用应用内部Assets资源
    

    从上面代码差异我们就知道,调用系统的时候不需要使用具体执行一个具体的ttf(simkai.ttf)库文件,但是需要指定一个具体的名字("simkai"),其实这个名字就是("simkai")就是指向了simkai.ttf 文件,那这个名字和具体的字体库文件是如何关联的吗(看着就像把字体库的全名(simkai.ttf)去掉.ttf的后缀得到的(simkai))?那具体是不是这样呢?答案是否定的,只是我们习惯的配置方式是这样配置而已,至于具体的配置在那里呢?

    frameworks/base/data/fonts/system_fonts.xml
    在该文件中添加字体库的nameset和fileset对应关系;

        <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>
    
    

    看到没,这里simkai的nameset指向了simkai.ttf的fileset。你也可以根据你自己的名字来命名;

    步骤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
    配置系统库字体,在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>
    

    特别注意:我们修改了这几个文件还需要注意一些编译细节,比如上述几个.xml文件都会被编译到/system/etc/目录下,但是我在Android 5.1 中编译了却有一个文件没有生效,那就是fonts.xml,经过比较,我发现系统中的fonts.xml没有我添加的内容,经过在系统中查找,发现了猫腻:
    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)
    

    上面这个代码的意思是把fonts-Rev.xml 编译到编译成fonts.xml,拷贝到/system/etc目录下;看到这里就知道为什么我的修改没生效了吧;我的修改先编译到/system/etc目录下,然后被这个fonts-Rev.xml编译的fonts.xml覆盖了(经过对比发现编译出来的/system/etc/fonts.xml果真和这个fonts-Rev.xml一模一样);两种解决办法:1,将我的修改添加到vendor/qcom/proprietary/qrdplus/globalization/engine目录下的fonts-Rev.xml;2,在vendor/qcom/proprietary/qrdplus/globalization/engine的Android.mk中将上面的那几行代码注释掉;

    相关文章

      网友评论

          本文标题:Android 添加字体库到系统

          本文链接:https://www.haomeiwen.com/subject/fdlcdxtx.html