Android中以粗暴的方式替换全局字体

简介:
本文讲的是 Android中以粗暴的方式替换全局字体, 在 Android 下使用自定义字体已经是一个比较常见的需求了,最近也做了个比较深入的研究。

那么按照惯例我又要出个一篇有关 Android 修改字体相关的文章,但是写下来发现内容还挺多的,所以我决定将它们拆分一下,分几篇来详细的讲解(可能是五篇)。主要会是一些常用的替换字体的方案,最后还会介绍一些全局替换的方案,当然也会包含最新的 『Fonts in XML』的方案。

期待你持续关注。

本篇是本系列的第二篇,之前已经发布的文章,有兴趣可以先看看。

Android 字体修改概述|开篇

修改字体需要了解 Typeface 的所有细节

一、前言

前面已经分析了修改字体的所有细节,以及与修改字体相关的 Typeface 类,接下来就开始讨论如何修改全局字体。

本篇会先介绍两种比较粗暴的方式来修改全局的字体。

二、自定义控件

在开始一个新的项目的时候,一般习惯好点的都会定义一个 BaseActivity 和 BaseFragment 来作为页面的基类,这样可以方便我们在之后的时候,对所有页面增加一些统一的逻辑。

不过应该不会有人提前想到要给所有的控件,提前定义一个自定义的控件实现。

但是如果在开发的初期,就已经考虑到字体需要修改的情况的话,是可以重写一些字体显示相关的控件。来达到全局替换字体的作用的。

Android 中,最常用的用来显示字体的控件,就是 TextView,这里就重写一个 TextView 来达到替换字体的效果。

在 TextView 中,可以通过 setTypeface() 方法,为 TextView 设置一个字体,setTypeface() 方法有两个重载方法,无非就是多传递了一个需要设置的 textStyle,用来标记粗体和斜体。

其实最终都是调用一个参数的 setTypeface(,它才是设置的关键。

可以看到,设置字体实际上是操作的 mTextPaint,mTextPaint 是 TextPaint 类的对象,直接继承自 Paint,就是一个用来绘制文字的画笔。

那么,我们就可以直接自定义一个 TextView ,在构造函数中,通过 setTypeface() 方法,来修改 TextView 的字体。

主要代码如下:

注意,这里还需要考虑在布局中,为我们设定的 FontTextView 设置的 textStyle 属性,可能是粗体或者斜体。

通常设计师为了考虑 App 的 UI 统一性和协调性,一般都会选用一个字体,所以将需要替换的字体封装在 FontTextView 中,也没有什么大的问题。

那么来验证看看实现出来的效果,这里专门选择了一个比较特殊的字体。在布局 xml 文件中,添加三个 FontTextView。

再来看看运行的效果。

这里也考虑了在布局中设置的 textStyle,并且一个已经比较倾斜的字体,使用 italic 标记之后,更倾斜了。

这个方法,如果在开发初期,还可以接受,无非就是写布局的时候,需要注意使用自定义的控件,同时还除了 TextView ,还需要重写 Button、EditText 等一系列需要显示文字的控件,说到底还是有点麻烦的。

而且如果是在一个已经成熟的项目上再使用这种方案,改动起来还是很费劲的,基本上就是一通文本替换,改动会比较大一些。

三、遍历 ViewTree

在 Android 中,用于显示文本的控件,都是直接或者间接集成自 TextView 的,那么我们只需要找一个合适的时机,遍历布局的 ViewTree,将其中所有 TextView 的子类都获取出来,然后批量修改它们的字体,同样也可以达到全局替换的效果。

在这个 replaceCustomFont() 的方法里,回去判断是否继承自 TextView,如果是就替换字体。如果不是,再判断是否是一个 ViewGroup,如果是的话,从其内取出所有的子 View,再递归调用 replaceCustomFont() 方法。

通常,为了在合适的时机修改字体,我们可以将这个方法加在 Activity.onCreate() 方法,或者 Fragment.onCreateView() 方法的后面,修改的地方,相对少一些,不过还需要考虑 ListView、RecyclverView 这种动态生成 View 的逻辑,也需要注意不能遗漏。

举个例子,写一个布局,在 Activity.onCreate() 方法中,调用 replaceCustomFont() 方法。

最后展现的效果如下。


使用这种方式,优点是,不需要修改 XML 布局,不需要重写多个控件。只需要在 Inflater View 的之后,调用一下 replaceCustomFont() 方法即可。

缺点也非常的明显,每个页面都需要修改,有动态加载 View 的地方可能会被遗漏,改动相比较之前的方案,稍微少一点。并且违背了组件的设计原则,实现方式也略显粗暴。同时它每次都会递归遍历 ViewTree,性能上多少都会有点影响。


本文作者: 张旸

来源:51CTO

原文标题:Android中以粗暴的方式替换全局字体
相关文章
|
Android开发
Android 自带的字体库、字体样式
Android 自带的字体库、字体样式
1066 0
Android 自带的字体库、字体样式
|
移动开发 Java Android开发
uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式
uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式
1324 0
uni-app&H5&Android混合开发三 || uni-app调用Android原生方法的三种方式
|
编解码 Android开发
性能优化:Android中Bitmap内存大小优化的几种常见方式
性能优化:Android中Bitmap内存大小优化的几种常见方式
|
存储 编解码 前端开发
Android自定义控件(八)——详解创建bitmap的方式
Android自定义控件(八)——详解创建bitmap的方式
231 0
Android自定义控件(八)——详解创建bitmap的方式
|
XML Android开发 数据格式
Android自定义控件(五)——圆形头像最简单的实现方式
Android自定义控件(五)——圆形头像最简单的实现方式
439 0
Android自定义控件(五)——圆形头像最简单的实现方式
|
JSON Android开发 数据格式
android中Json数据保存方式
android中Json数据保存方式
165 0
|
存储 XML 设计模式
一个简单的Android网络访问全局码判断及通用数据解析方案
我们在开发中,网络请求经常会遇到各种错误码的判断。比如下面这样:
119 0
|
移动开发 Dart 前端开发
这么多移动开发的方式,传统方式写安卓、IOS 还有出路吗?
我所说的传统的方式是指,用 Java 或者 Kotlin 写安卓,用 Object-C 或者 Swift 写 IOS。
250 0
这么多移动开发的方式,传统方式写安卓、IOS 还有出路吗?
|
存储 缓存 Java
Android 百度语音合成 (含离线、在线、API合成方式,详细步骤+源码)
Android 百度语音合成 (含离线、在线、API合成方式,详细步骤+源码)
498 0
Android 百度语音合成 (含离线、在线、API合成方式,详细步骤+源码)
|
Android开发
android activity方式的dialog
android activity方式的dialog
148 0
android activity方式的dialog