再仔细看看 LayoutInflater.from()
方法的源码。
可以看到,这里获得 LayoutInflater 对象的时候,用到的就是 LAYOUT_INFLATER_SERVICE。
所以 CalligraphyContextWrapper.getSystemService() 方法被重写的目的,就是为了替换掉 LayoutInflater 对象,所以可以猜想,设置自定义字体的地方,就在自定义的 LayoutInflater 中。
继续查看 CalligraphyLayoutInflater 的源码,最终修改字体的逻辑,是在 CalligraphyContextWrappe 的 onViewCreatedInternal()
方法里面。
它会取出我们自定义属性上设置的值,然后设置到初始化好的 TextView 上去。
四、Calligraphy 小结
到此就完成了 Calligraphy 的主要逻辑追踪,几个核心技术点:
Calligraphy 不需要重写 TextView 之类的控件。
Calligraphy 重写了 LayoutInflater 。
Calligraphy 在
attachBaseContext()
方法中,替换掉 ContextWrapper。又通过自定义的 ContextWrapper 的
getSystemService()
方法,将 LayoutInflater 替换成库里重写的 CalligraphyLayoutInflater。在 CalligraphyLayoutInflater 中,拦截我们需要的 TextView 和其子类,对它们的字体替换成我们设置的字体。
当然,实际上,开源库之所以可以流传的比较广,它还做了更多的细节处理,但是我们一般分析开源库,只需要关心主线逻辑就可以了。
整体来说 Calligraphy 没有什么大毛病,可以放心使用,当然如果你用了一些同样依赖此原理的第三方库,可能会有冲突,这个就只能具体问题具体分析了。
,今天在头条私信承香墨影,回复『成长』。我会送你一些我整理的学习资料,包含:Android反编译、算法。Web项目源码。