怎样“无痛”全局替换字体
来源:互联网 发布:阿里云服务器上传网站 编辑:程序博客网 时间:2024/05/07 17:16
序
在 Android 下使用自定义字体已经是一个比较常见的需求了,最近也做了个比较深入的研究。
那么按照惯例我又要出个一篇有关 Android 修改字体相关的文章,但是写下来发现内容还挺多的,所以我决定将它们拆分一下,分几篇来详细的讲解。主要会是一些常用的替换字体的方案,最后还会介绍一些全局替换的方案,当然也会包含最新的 『Fonts in XML』的方案。
期待你持续关注。
本篇是本系列的第六篇,之前已经发布的文章,有兴趣可以先看看。
- Android 字体修改概述|开篇
- 修改字体需要了解 Typeface 的所有细节
- 简单粗暴的方式,修改字体
- 利用反射,修改全局字体
- 利用 AppCompatDelegate ,全局替换全局字体
一、前言
上一篇讲解了通过替换 AppCompatDelegate 来达到替换控件的目的,从而替换成我们需要的可设置自定义字体的控件,来达到替换字体的目的。
现在大多数人应该看出来了,到最后实现的目标就是如何快速、低入侵的替换全局控件,然后对这些控件进行重写,就可以达到我们很多的目的。换字体只是这其中的一种应用,还有其它的,例如:换肤、无痕埋点等等,都是有可借鉴的地方的。
本文再介绍一种方式,通过 LayoutInflaterCompat.setFactory()
替换掉 LayoutInflaterFactory 或者 LayoutInflater.Factory2,来达到我们替换控件的目的,从而实现全局字体的替换。
接下来开始介绍所有的技术细节。
二、setFactory()
2.1 setFactory() 的技术原理
对大家而言,LayoutInflater 应该是不陌生的,所有需要动态加载 layout-xml 中的 View 的地方都需要用到它的 inflater()
方法,例如:ListView、RecyclerView。
而本文需要用到的是它另外两个 Api 方法,setFactory()
和 setFactory2()
。它们的方法签名如下。
/setFactory.png
这两个方法分别接收 Factory 和 Factory2 ,它们两个都是 Interface。并且这两个方法的功能也是类似的。只是 setFactory2()
是在 Api Level 11 之后引入的,使用那个取决于项目的 minSdkVersion。
不过一般而言,我们也不需要直接使用它。我们需要只用 Support.v4 包中,为我们提供的 LayoutInflaterCompat 这个兼容类来做处理。和所有的兼容类一样,它其中会有一个 IMPL的变量,会根据不同的 Api Level 初始化不同的实例。
/compatImpl.png
可以看到,这里只对 Api Level 21 作为一个分界,去处理逻辑,其中会有不同的实现,这里有兴趣可以一探究竟,有时间会单独出一篇文章来讲解,这里就不再深入了。
这里,我们需要用到 LayoutInflaterCompat.setFactory()
方法,它实际上已经被标记为 @Deprecated
了,一般推荐我们使用 LayoutInflaterCompat.setFactory2()
,但是它们的功能是一致的,这里就不纠结这些细节了。
/impl-setfactory.png
可以看到,setFactory()
接收一个 LayoutInflaterFactory 的对象,它实际上是一个接口,需要我们实现其中的 onCreateView()
方法。
/LayoutFactory.png
我们这里主要的功能,就在于实现 onCreateView()
方法,将我们需要的控件在这个方法中替换掉。
2.2 举个例子
对着源码说太干了。下面我举个实际的例子,相信就可以说明问题了。
首先我新建一个 Activity,在 super.onCreate()
之前,通过 LayoutInflaterCompat 重新设置 Factory,在关键地方打印好 Log。
/setfactory-javacode.png
再声明一个布局,让它去显示 layout-XML 布局,层级很简单,就是一个 LinearLayout 中间包含了一个 TextView。
然后,我们运行起来看看输出的 Log ,这里撇开了 DecorView 等这些布局的打印,只看关键部分。
/setFactory-log.png
从 Log 输出可以看出,实际上,你所有布局的控件,都会经过 LayoutInflaterFactory.onCreateView()
方法走一遍,去实现初始化的过程,在其中可以有效的分辨出是什么控件,以及它有什么属性。
并且 onCreateView()
方法的返回值,就是一个 View,如果要替换该 View,可以在此处将其初始化后返回回去即可。
三、利用 LayoutInflater 替换字体
既然原理都清楚了,那么我们接下来就开始实际操作一下,如何通过替换 LayoutInflaterFactory 来达到替换控件,从而达到替换字体的目的。
首先,定义一个 Activity 为基类,其中在 super..onCreate()
方法之前,调用 LayoutInflaterCompat.setFactory()
,然后将它的替换为 我们自己定义的 CustomFontCompatDelegate 类。
/demo-activitycode.png
CustomFontCompatDelegate 的实现,也非常的简单,只需要在它的 onCreateView()
方法中,替换掉 TextView 就可以。
/demo-delegate-code.png
其实,所有替换字体的逻辑,都在 FontTextView 中,接下来我们再看看 FontTextView 的逻辑。
/fontTextView.png
可以看到,在 FontTextView 中,直接完整的将字体替换成我们在 assets 目录下存放的 custom_font.ttf
字体文件。
到这里就完成了基本的功能,我们接下来看看如何使用它。
只需要使用一个 Activity ,继承我们刚才实现的 CustomFontActivity,然后写一个简单的布局,其中有三个 TextView。
/demo-activityxml.png
最后,我们再来看看运行后的效果。
/f-fontimage.png
四、小结
到这里基本上就介绍清楚如何通过 LayoutInflaterCompat.setFactory()
去替换 Factory 这个接口,达到我们替换控件的目的,从而完美的替换全局的字体。
但是实际开发过程中,依然需要考虑所有可以显示文字的控件,例如:TextView、EditText、Button 等等,这些都是我们需要重写的控件。
- 怎样“无痛”全局替换字体
- Android 替换全局字体
- 全局替换字体,开源库更方便!!!
- 全局替换安卓应用字体
- Android 5.0以上 app全局字体替换
- android全局替换字体最新方案
- PADS:怎样全局替换元件封装
- PADS:怎样全局替换元件封装
- Android 全局替换第三方字库(自定义字体)
- 简单高效的实现Android App全局字体替换
- 简单高效的实现Android App全局字体替换
- 简单高效的实现Android App全局字体替换
- 太激动!Android修改全局字体样式,替换整个APP字体
- vi全局替换命令
- vim 全局批量替换
- js全局替换
- vim全局替换命令
- vim全局替换命令
- 页面前进一页
- 坚持#第224天~零基础自学云计算基础语言应用之Shell18~22节
- 银行数据
- 如何让文本可复制
- 五天面试五家硅谷顶尖公司并拿到五个Offer
- 怎样“无痛”全局替换字体
- JMETER BEANSHELL SAMPLE 加密
- Spring Boot系列01-Spring Boot + maven 实现Hello World
- mac 中 Apache
- 解决springMVC4下使用@ResponseBody 返回json数据的中文乱码问题
- Android多线程断点续传
- 浅谈JavaScript严格模式
- is-a 和 has-a
- activity1