在 Android 下使用自定义字体已经是一个比较常见的需求了,最近也做了个比较深入的研究。
那么按照惯例我又要出个一篇有关 Android 修改字体相关的文章,但是写下来发现内容还挺多的,所以我决定将它们拆分一下,分几篇来详细的讲解。主要会是一些常用的替换字体的方案,最后还会介绍一些全局替换的方案,当然也会包含最新的 『Fonts in XML』的方案。
之前已经介绍了很多种,快速、低入侵的替换全局字体的方式。但是大多数情况下,我们需要实现的功能,一定已经有现成的实现方案。
本文就介绍一个 Github 上,比较火的全局替换字体的开源库,差不多阅读文档加集成,一个小时全局替换字体不是梦。
这个开源替换字体库就是 Calligraphy:
既然是要接入开源库来全局替换字体,先来看看它可以实现的效果。
接下来,我们开始一步步集成它。
Calligraphy 支持 Gradle 和 jar 的接入方式,这里使用 Gradle 来接入。
Calligraphy 支持的文件,可以放在 assets/ 目录下,当然,我们可以再在其中建立一个文件夹来专门的存放字体文件。
Calligraphy 使用 CalligraphyConfig 类,来进行初始化。它需要在 App 的入口,Application.onCreate() 中调用。
初始化主要是为了指定一些默认的配置,例如:默认字体、默认属性值。
Calligraphy 对 Activity 的 Context,进行了一次包装,需要使用它包装的 Context,才可以达到替换字体的效果。所以还需要重写 BaseActivity 中的 attachBaseContext() 方法,将其替换成 Calligraphy 为我们提供的 Context 的包装类 CalligraphyContextWrapper。
到这里,就完成了 Calligraphy 的配置了,我们只需要在 TextView 中,通过属性去使用它就好了,它配置的是我们字体文件,在 assets 目录下的路径。
Calligraphy 使用起来还是很方便的,并且也支持更多的配置方式,例如: Style、Theme 都可以。
具体的使用细节,大家还是阅读文档了解更方便。
我们使用一个开源库,当然要理解它的原理才能放心使用在商业项目上,接下来,我们就来分析一下 Calligraphy 的实现原理,看看和之前介绍的方式,有没有什么区别。
先来看看 Calligraphy 的整体结构。
可以看到,它一共需要的类非常的少,算是一个比较精简的库了,并且它并没有重写 TextView ,所以应该是通过其它的方式来做到字体的替换的。
我们先来看看在 Application 需要调用的配置类, CalligraphyConfig 的源码。
CalligraphyConfig 使用 Builder 的模式去初始化自己,可以看到这里只是设置了一些配置项,并没有实际的业务逻辑。
CalligraphyConfig 初始化之后,就以静态变量存储起来,供其它地方使用,是一种单例的模式,但是并没有考虑线程安全的问题。
既然 CalligraphyConfig 没有实际的逻辑,那么接下去应该如何追踪重要的代码呢?
仔细观察之前配置项里,需要重写 Activity.attachBaseContext() 方法,这里会传递它重写的一个 Context 的包装类 CalligraphyContextWrapper,所以接下来我们再看看 CalligraphyContextWrapper 的源码逻辑。
读了 CalligraphyContextWrapper 源码之后,你会发现它最重要的就是重写了 getSystemService() 方法,当它是 LAYOUT_INFLATER_SERVICE 的时候,将自己的 CalligraphyLayoutInflater 类,返回回去。
那么,这里的 LAYOUT_INFLATER_SERVICE 到底是什么呢?
我想大家应该对 LayoutInflater 不陌生,从 layout-xml 加载 View 的时候,都需要用到它,相信下面这段代码,应该大家都不陌生。
再仔细看看 LayoutInflater.from() 方法的源码。
可以看到,这里获得 LayoutInflater 对象的时候,用到的就是 LAYOUT_INFLATER_SERVICE。
所以 CalligraphyContextWrapper.getSystemService() 方法被重写的目的,就是为了替换掉 LayoutInflater 对象,所以可以猜想,设置自定义字体的地方,就在自定义的 LayoutInflater 中。
继续查看 CalligraphyLayoutInflater 的源码,最终修改字体的逻辑,是在 CalligraphyContextWrappe 的 onViewCreatedInternal()方法里面。
它会取出我们自定义属性上设置的值,然后设置到初始化好的 TextView 上去。
到此就完成了 Calligraphy 的主要逻辑追踪,几个核心技术点:
当然,实际上,开源库之所以可以流传的比较广,它还做了更多的细节处理,但是我们一般分析开源库,只需要关心主线逻辑就可以了。
整体来说 Calligraphy 没有什么大毛病,可以放心使用,当然如果你用了一些同样依赖此原理的第三方库,可能会有冲突,这个就只能具体问题具体分析了。
原文来自: 承香墨影
声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com
支持全球约2.4万个城市地区天气查询,如:天气实况、逐日天气预报、24小时历史天气等
支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景
涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。
根据给定的手机号、姓名、身份证、人像图片核验是否一致
通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。