Android更换字体

项目中的字体不入设计师法眼,非要换。遇到一些问题,刚好总结一下。

1.全局更改字体样式

支持ttfotfttc格式

存放位置:(xxx为字体文件名字)
res/font/xxx.ttf

res目录下新建font资源文件夹
Android更换字体_第1张图片
resourceType选择font
Android更换字体_第2张图片
再讲资源文件放入该目录下,注意:命名要小写

使用方式
在项目manifest文件的Applicationtheme标签下对应的文件中,添加,即可全局替换

<item name="android:fontFamily">@font/siyuan_regularitem>

<item name="android:includeFontPadding">falseitem> 

2.局部替换某个TextView的字体

去除theme中设置的代码,直接在某个TextView的布局文件中设置

<TextView
    android:id="@+id/tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/simkai"
    android:text="测试字体" />

3.字体替换问题记录

一开始替换字体,按照以上步骤替换后,部分页面文字有很大的上下间距空白,有些字体就没有,布局文件如下


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    
    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#cc33ff"
        android:fontFamily="@font/simkai"
        android:text="楷体"
        android:textSize="20sp" />

    
    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:background="#cc33ff"
        android:fontFamily="@font/siyuan_regular"
        android:text="思源黑体"
        android:textSize="20sp" />

LinearLayout>

相同字号大小,都是WrapContent布局,但是显示的页面效果,如下
Android更换字体_第3张图片
可以看到楷体就能很完美的适配,但是思源黑体就不行,初步以为是字体文件的问题,后来不同网站下载的思源黑体都有相同问题,后来以为是字体后缀的问题,尝试后也确定没关系。然后更改字体文件,删除韩语日语等,还是没效果。最后根据这篇文章找到了问题的原因。

Android的字体5条线
Android更换字体_第4张图片
思源黑体字体计算高度的时候不同平台用的字段不同,默认是

head.xMin = FontBBox.xMin
head.yMin = FontBBox.yMin
head.xMax = FontBBox.xMax
head.yMax = FontBBox.yMax

Adobe中用FontBBox字段,Android中用head字段,根本原因是

是因为类似于竖排破折号(有两个字高度和三个字高度)导致FontBBox和head字段被撑大了,而Android又依赖于head.yMin和head.yMax来写字导致的。

解决方式
1.基于已经发布的字库,用adobe的字库工具修改后重新生成。
(试过,但是很卡,可能字体文件解析或者重新生成很麻烦,而且字段很多,容易改错。)
2.通过设置textview.setIncludeFontPadding(false)来使用ascent/descent而非top/bottom(即head.yMax/head.yMin)来进行排版。
(即theme中直接设置去除字体的内Padding计算)

你可能感兴趣的:(android,java,apache)