设计师说,我们要在 App 里用十种字体!!!
序
在 Android 下使用自定义字体已经是一个比较常见的需求了,最近也做了个比较深入的研究。
那么按照惯例我又要出个一篇有关 Android 修改字体相关的文章,但是写下来发现内容还挺多的,所以我决定将它们拆分一下,分几篇来详细的讲解。主要会是一些常用的替换字体的方案,最后还会介绍一些全局替换的方案,当然也会包含最新的 『Fonts in XML』的方案。
期待你持续关注。
本篇是本系列的第六篇,之前已经发布的文章,有兴趣可以先看看。
Android 字体修改概述|开篇
修改字体需要了解 Typeface 的所有细节
简单粗暴的方式,修改字体
利用反射,修改全局字体
利用 AppCompatDelegate ,全局替换全局字体
通过修改 LayoutInflater,全局替换字体!
一、前言
之前写了很多关于如何在成熟项目中,快速、低入侵的替换全局的字体。但是通常,如果设计师有替换字体的要求,一般不会只使用一个字体,而是会有多个不同的字体文件,根据不同的显示位置,加载不同的字体文件。
那么本文,就介绍如何通过自定义属性,来指定需要的字体,从而实现加载多字体文件的需求。
如何使用 LayoutInflater.setFactroy() 动态替换控件,这是本文的基础,如果不太明白的可以先看看之前的文章《利用 LayoutInflater,优雅的替换全局字体》。
二、自定义属性
既然,我们已经需要重写 TextView、Button 这一系列显示文字的控件,那么如何区分它们加载那个字体文件,我第一个想到的就是使用属性来完成。
对于自定义属性,其实用起来非常的简单,一般通过几个步骤,就可以简单使用。
- 编写自定义 View 类。
- 编写 values/attrs.xml,编写 styleable 或者 attr 标签。
- 在 layout-xml 布局中,使用自定义属性。(需要注意 namespace)。
- 在自定义 View 中,通过 TypedArray 或者 AttributeSet 获取到我们自定义的属性。
其实,自定义属性非常的灵活,定义的时候可以选择使用 declare-styleable 或者 attr 标签来定义它,而获取的时候,也可以选择使用 TypedArray 或者 AttributeSet 来获取它。这些都非常的灵活,我们按照自己的需要设定和获取就好了,没什么好细说的,有关自定义属性,可以单独写一篇文章了,就不在这里赘述了,有空再单独总结。
三、使用自定义属性的 Demo
既然已经明确了方案,会使用 LayoutInflater.setFactory() 来替换 TextView 控件,在 TextView 控件中,通过获取自定义属性的值,拿到我们定义的数据,根据自定义数据的值,为 TextView 加载不同的字体文件。
那么接下来就让我们实际操作一下,看看如何实现吧。
3.1 准备工作
首先我们需要有多个字体文件,这里把它存储在 assets 目录下面。
这里使用了 6 个不同的字体文件,它们是 .otf 格式的。
然后就可以编写我们需要的自定义属性了。
因为我们本身字体有点多,所以这里使用了一个枚举类型的 attr 来区分,为每种字体设置一个简称,这样可以简化我们后续的操作。
接下来就可以开始编写我们的自定义 FontAppCompatText 了。
在 FontAppCompatText 中,从 AttributeSet 中,获取到我们通过自定义属性设定的字体,然后根据属性设定字体,分别加载不同的字体文件。当然你也可以用 TypedArray ,获取的方式略有不同。
这里用到了 Typeface,它可以帮我们加载字体文件。如果不了解的,可以先看看之前的文章《想要修改 Android 字体,先了解一下 Typeface 吧》。
然后,我们还需要一个 BaseActivity ,在其中的 onCreate() 方法中,调用替换控件需要的 LayoutInflaterCompat.setFratory() 方法。
到这里,前期的准备工作就已经做好了,我们只需要使用它们就好了。
3.2 使用属性加载多字体
首先,我们需要有一个 Activity,来继承 CustomFontActivity 。
在其中加载的 layout-xml 布局中,写很多个 TextView ,分别使用我们之前自定义属性 font ,来配置不同的字体。
需要注意的是,因为这里使用了自定义属性,所以需要在根布局上,添加 xmlns:fonts="http://schemas.android.com/apk/res-auto"" ,一般 IDE 也会有警告,我们忽略它就可以了,使用 tools:ignore="MissingPrefix"设置忽略,当然,这里由引入了 tools 这个命名空间,所以还需要加上 xmlns:tools="http://schemas.android.com/tools"。
到这里就已经完成了我们使用自定义属性,区分 TextView 加载不同的字体的要求了。
找个设备运行一下,看看效果如何。