全局替换字体,开源库更方便!!!

简介:

一、前言

之前已经介绍了很多种,快速、低入侵的替换全局字体的方式。但是大多数情况下,我们需要实现的功能,一定已经有现成的实现方案。

本文就介绍一个 Github 上,比较火的全局替换字体的开源库,差不多阅读文档加集成,一个小时全局替换字体不是梦。

这个开源替换字体库就是 Calligraphy:

https://github.com/chrisjenx/Calligraphy

二、如何使用Calligraphy

既然是要接入开源库来全局替换字体,先来看看它可以实现的效果。

/screenshot.png

接下来,我们开始一步步集成它。

2.1 添加 Gradle 依赖

Calligraphy 支持 Gradle 和 jar 的接入方式,这里使用 Gradle 来接入。

/gradle-denpen.png

2.2 添加字体文档到项目内

Calligraphy 支持的文件,可以放在 assets/ 目录下,当然,我们可以再在其中建立一个文件夹来专门的存放字体文件。

/assets-font-file.png

2.3 初始化 Calligraphy

Calligraphy 使用 CalligraphyConfig 类,来进行初始化。它需要在 App 的入口,Application.onCreate() 中调用。

/init-method.png

初始化主要是为了指定一些默认的配置,例如:默认字体、默认属性值。

2.4 替换 Context

Calligraphy 对 Activity 的 Context,进行了一次包装,需要使用它包装的 Context,才可以达到替换字体的效果。所以还需要重写 BaseActivity 中的 attachBaseContext() 方法,将其替换成 Calligraphy 为我们提供的 Context 的包装类 CalligraphyContextWrapper。

/attach-base-context.png

2.5 使用 Calligraphy

到这里,就完成了 Calligraphy 的配置了,我们只需要在 TextView 中,通过属性去使用它就好了,它配置的是我们字体文件,在 assets 目录下的路径。

/text-layout-xml.png

2.6 查缺补漏

Calligraphy 使用起来还是很方便的,并且也支持更多的配置方式,例如: Style、Theme 都可以。

具体的使用细节,大家还是阅读文档了解更方便。

三、Calligraphy的原理

我们使用一个开源库,当然要理解它的原理才能放心使用在商业项目上,接下来,我们就来分析一下 Calligraphy 的实现原理,看看和之前介绍的方式,有没有什么区别。

先来看看 Calligraphy 的整体结构。

/call-path.png

可以看到,它一共需要的类非常的少,算是一个比较精简的库了,并且它并没有重写 TextView ,所以应该是通过其它的方式来做到字体的替换的。

我们先来看看在 Application 需要调用的配置类, CalligraphyConfig 的源码。

/config-methon.png

CalligraphyConfig 使用 Builder 的模式去初始化自己,可以看到这里只是设置了一些配置项,并没有实际的业务逻辑。

/config-get.png

CalligraphyConfig 初始化之后,就以静态变量存储起来,供其它地方使用,是一种单例的模式,但是并没有考虑线程安全的问题。

既然 CalligraphyConfig 没有实际的逻辑,那么接下去应该如何追踪重要的代码呢?

仔细观察之前配置项里,需要重写 Activity.attachBaseContext() 方法,这里会传递它重写的一个 Context 的包装类 CalligraphyContextWrapper,所以接下来我们再看看 CalligraphyContextWrapper 的源码逻辑。

/getSystemServer.png

读了 CalligraphyContextWrapper 源码之后,你会发现它最重要的就是重写了 getSystemService() 方法,当它是 LAYOUT_INFLATER_SERVICE 的时候,将自己的 CalligraphyLayoutInflater 类,返回回去。

那么,这里的 LAYOUT_INFLATER_SERVICE 到底是什么呢?

我想大家应该对 LayoutInflater 不陌生,从 layout-xml 加载 View 的时候,都需要用到它,相信下面这段代码,应该大家都不陌生。

/layoutinfalter-code.png

再仔细看看 LayoutInflater.from() 方法的源码。

/layoutinflalter-from.png

可以看到,这里获得 LayoutInflater 对象的时候,用到的就是 LAYOUT_INFLATER_SERVICE。

所以 CalligraphyContextWrapper.getSystemService() 方法被重写的目的,就是为了替换掉 LayoutInflater 对象,所以可以猜想,设置自定义字体的地方,就在自定义的 LayoutInflater 中。

继续查看 CalligraphyLayoutInflater 的源码,最终修改字体的逻辑,是在 CalligraphyContextWrappe 的 onViewCreatedInternal() 方法里面。

/view-create-interval.png

它会取出我们自定义属性上设置的值,然后设置到初始化好的 TextView 上去。

四、Calligraphy 小结

到此就完成了 Calligraphy 的主要逻辑追踪,几个核心技术点:

  1. Calligraphy 不需要重写 TextView 之类的控件。
  2. Calligraphy 重写了 LayoutInflater 。
  3. Calligraphy 在 attachBaseContext() 方法中,替换掉 ContextWrapper。
  4. 又通过自定义的 ContextWrapper 的 getSystemService() 方法,将 LayoutInflater 替换成库里重写的 CalligraphyLayoutInflater。
  5. 在 CalligraphyLayoutInflater 中,拦截我们需要的 TextView 和其子类,对它们的字体替换成我们设置的字体。

当然,实际上,开源库之所以可以流传的比较广,它还做了更多的细节处理,但是我们一般分析开源库,只需要关心主线逻辑就可以了。

整体来说 Calligraphy 没有什么大毛病,可以放心使用,当然如果你用了一些同样依赖此原理的第三方库,可能会有冲突,这个就只能具体问题具体分析了。


本文转自承香墨影博客园博客,原文链接:http://www.cnblogs.com/plokmju/p/7685581.html,如需转载请自行联系原作者


相关文章
|
11天前
|
自然语言处理 IDE 前端开发
5个可保存的在线代码片段平台推荐-变成自己的代码词典库
5个可保存的在线代码片段平台推荐-变成自己的代码词典库
69 0
|
11天前
|
JavaScript 前端开发
5款MicrosoftEdge扩展推荐(亲测有用 极力推荐
5款MicrosoftEdge扩展推荐(亲测有用 极力推荐
83 0
5款MicrosoftEdge扩展推荐(亲测有用 极力推荐
|
11天前
|
SQL 开发框架 .NET
你知道Golang的模板怎么用吗?带你了解动态文本的生成!
你知道Golang的模板怎么用吗?带你了解动态文本的生成!
|
6月前
每次都要写一堆样式代码?试试ViewModifier建立统一的样式规范吧
每次都要写一堆样式代码?试试ViewModifier建立统一的样式规范吧
47 1
antd组件库封装44-添加字体变量方案
antd组件库封装44-添加字体变量方案
67 0
antd组件库封装44-添加字体变量方案
Flutter如何将文本与图片混合编辑?(功能扩展篇)
一个优秀的富文本,应该包含优秀的排版算法、丰富的功能和渲染的高性能。在上一篇中,我们实现了可扩展的、基础的富文本编辑器。那么在本文中,让我们对富文本进行更多功能的扩展。
Flutter如何将文本与图片混合编辑?(功能扩展篇)
Flutter入门:设置全局字体
引入字体 首先在项目中创建fonts目录,然后将将ttf文件放到该目录下,然后在pubspec文件中添加该字体文件
755 0
|
JSON JavaScript 数据可视化
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(二)
UI库提供了很多组件,组件又带有很多属性,有一些常用属性我们可以记住并且手撸,但是有些不常用的属性,或者需要设置多个属性,这样的情况下写起来就麻烦了,有时候还要打开帮助文档看看属性是怎么设定的,需要设置什么样的属性值。那么有没有优雅的方式来设置组件的各种属性呢?我做了一个在线小工具,可以方便的设置属性,并且可以实时看到效果。
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(二)
|
JSON 数据可视化 JavaScript
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(一)
UI库提供了很多组件,组件又带有很多属性,有一些常用属性我们可以记住并且手撸,但是有些不常用的属性,或者需要设置多个属性,这样的情况下写起来就麻烦了,有时候还要打开帮助文档看看属性是怎么设定的,需要设置什么样的属性值。那么有没有优雅的方式来设置组件的各种属性呢?我做了一个在线小工具,可以方便的设置属性,并且可以实时看到效果。
UI库组件属性太多不知道啥意思?没关系来看看可视化设置(一)
VB源码升级后的几幅截图-VBIDE嵌入窗体、代码资源自动加入
用了整整两天的时间终于完成了功能上的升级,但多国语言版和数据库的加密还不知什么时间能做完,所以一时还不能发布,不过作为“内部人员”倒是可以先用为快:)
529 0