在 Android 下使用自定义字体已经是一个比较常见的需求了,最近也做了个比较深入的研究。

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

期待你持续关注。

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

一、前言

本文依然属于 Android 修改字体的系列,本系列开始会介绍一些比较方便的全局修改的方案,越往后的方案可能会越好一些,但是不一定最适用你现在的项目。

今天介绍的就是其中的一个,使用反射的方式,修改 Typeface 中的某个字体,来达到全局替换的目的。

二、替换默认字体的思路

本文的很多预备的知识点,应该在之前的文章中就已经说清楚了,有兴趣可以去看看完整的文章,《想修改 Android 字体,你需要先了解一下 Typeface!!!》。

这里为了保证逻辑完整,还是大概说一下思路。

2.1 修改Typeface 的某个默认字体

首先需要明确一点,在 Android 中,所有操作字体的动作,都会使用到 Typeface 这个类。而系统默认的一些字体,也会在 Typeface 被加载的时候进行初始化,因为这些步骤在它的静态代码块内完成。

而这些字体都会定义成了 static final 的,所以一般我们是不能去修改它们的。

但是我们是可以使用反射的方式去修改被标记为 static final 的常量的,这个后面再将细节。

也就是说,我们只需要在初始化的实际,替换掉某个默认的字体,然后在Theme 内将默认字体字体标记为该字体,就可以达到替换的目的。

2.2 在 TextView 中默认的字体

在 TextView 的构造方法里,设置字体的方法是 setTypefaceFromAttrs() ,下面是该方法的方法签名。

在该方法的参数中,如果 familyName 为 null 的时候,会根据传入的 typefaceIndex 去设置对应的字体,传入到 setTypeface() 方法中。

再来看看 TextView 的构造方法中,获取这几个参数的地方。在默认什么都不设置的情况下, familyName 就是为 null,而 typefaceIndex 为 -1。这两个参数会先从 TextAppearance 中读取属性,再从 TextView 本身设置的 xml 属性中读取,后者会覆盖前者。

可是 typefaceIndex 还会有一些其它的操作,例如 inputType 为 password 的时候,就会强行修改为 MONOSPACE。

最终,将处理后的结构,传递给 setTypefaceFromAttrs() 方法。

通过这些细节,我们就可以了解到,是在有一些情况下,是可以保证 TextView 使用的是我们的某个被加载到 Typeface 中的默认字体的。

条件就是:

fontFamily ==null&& typefaceIndex != -1

2.3 在 Theme 中,修改字体为默认字体样式

对于一些默认的字体样式,是可以直接在 Theme 中进行设置的,它的优先级低于在页面布局的 xml 中,为 TextView 设置的字体样式,但是如果不设置,那么在 Theme 中的设置将会生效。

这个没什么好说的,我这里用的主题就是 AppTheme,所以我在它里面修改 android:typeface 就可以了。

三、通过反射修改字体

到这里,基本的概念就已经讲解清楚了,那么我们就开始实际编写代码来替换字体了。

3.1 修改 Theme

在 App 的主题中,修改 android:typeface 为 serif。

注意,这里随便选了一个默认字体,实际上使用 monospace 也是可以的,只需要和后面我们替换的字体保持一致即可。

当然这里不推荐使用 monospace ,因为 TextView 本身还有一些逻辑会将 typefaceIndex 设置成 monospace,所以我们不要替换它比较好。

3.2 通过反射修改 Typeface 的字体

在 Typeface 中,是有一些被标记为 static final 的默认字体,因为上一步的 Theme 中,就是设置的 serif ,所以我们这里替换它就好了。

完整的方法非常的简单,就是通过反射拿到 Typeface.SERIF,然后使用反射将它修改成我们需要的字体即可。

因为这里修改了 static final 的值,所以需要额外调用 setAccessible() 方法,它会修改 AccessibleObject 中的 overide 为 true,这个标记的意思,就是关闭对这个字段改写的安全检查,从而让我们可以替换 static final 的字段。

3.3 在入口的地方,调用替换的方法

接下来就清晰了,我们只需要在 App 启动的时候,调用一下 changeDefaultFont() 方法。

这里直接在 Application.onCreate() 方法中,调用即可。

3.4 验证运行结果

这个没什么了,直接写个 Demo,正常使用 TextView 就可以了。

【本文为51CTO专栏作者“张旸”的原创稿件,转载请通过微信公众号联系作者获取授权】

【编辑推荐】

【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0

android反射改theme,全局修改默认字体,通过反射也能做到相关推荐

  1. origin设置不同区域的颜色_[测试狗]Origin入门教程(二十四):效率翻倍小技巧——修改默认字体...

    在使用Origin的时候,对于每次绘图都需要更改字体觉得很麻烦,因为Origin默认的字体为Arial,但是我们常用的字体一般为Times New Roman,在下拉框的很底部,每次更改都很浪费时间. ...

  2. Android 11源码 Framework修改默认usb连接模式为MTP模式

    Android 11源码 Framework修改默认usb连接模式为MTP模式 Android 11源码 Framework修改默认usb连接模式为MTP模式 修改Framework层源码 编译修改后 ...

  3. xshell修改默认字体字号、配色方案(背景)

    演示版本:Xshell6_plus下载 xshell修改默认字体字号.配色方案(背景) 1.打开:文件→属性 (或者按快捷键Alt+P) 2.设置字体.字号 我选择的是Consolas字体,10号大小 ...

  4. Word修改默认字体和段落的方法

    在进行毕业设计论文撰写时老师会要求所有的汉字的字体为宋体,英文和数字的字体为Times New Roman,段落两端对齐,首行缩进2字符,段前段后0磅,行间距21磅,如果等全部撰写完之后再慢慢改字体会 ...

  5. Word修改默认字体

    在Win10的最近一次更新后,发现我的office365默认字体都给我改成等线,什么鬼,以前都是宋体,现在这个还真的不习惯,就动手修改默认字体,设置如下: 1.在word空白处点击鼠标右键,选择字体. ...

  6. zabbix修改默认字体

    zabbix修改默认字体 在zabbixweb界面里有时候显示界面为框框 所以修改默认字体 现在windows里 随便找个字体: win+R 搜fonts 然后随便复制了一个字体,传到zabbix服务 ...

  7. python系统字体_Python matplotlib修改默认字体的操作

    matplotlib库作为Python常用的数据可视化库,默认字体居然不支持中文字体,必须得吐槽一下~ 闲言少叙,开始正文 方法1:在plot中指定prop参数 使用matplotlib.font_m ...

  8. visio修改默认字体

    visio没有同word一样通过样式或者通过设计→默认字体的方式来修改默认字体,通常只能选择所有内容然后设置字体,但新建的图形中字体又会变回默认,我找到了一种修改visio默认字体的方法,以下操作基于 ...

  9. Axure 9 修改默认字体

    Axure 9 修改默认字体 一.修改默认字体 1.点击:项目–>元件样式管理器. 2.可以点击任意控件去修改该控件的默认字体以及相关的参数. 3.如何修改全部默认字体? 点击Default,然 ...

  10. MT8788 Android11 修改默认字体,字体大小和像素密度

    环境:     MT8788 Android11 ili9881p_hd720_dsi_vdo 1.修改默认语言 目录: b/device/mediateksample/tb8788p1_64_bsp ...

最新文章

  1. 【布局】圣杯布局双飞翼布局
  2. Atitit..css的体系结构
  3. 基于pytorch开发CNN提取全连接层作为特征
  4. ajax mysql项目 react_Github MIT开源银行电子支付系统(ReactJS+Nodejs+Mysql)
  5. P7854-「EZEC-9」GCD Tree【构造】
  6. bzoj 2257[Jsoi2009]瓶子和燃料 数论/裴蜀定理
  7. CDH报错: 主机的 NTP 服务未同步至任何远程服务器
  8. Tensor的Broadcasting操作
  9. 江苏计算机类事业编总分多少,必看!江苏事业单位统考三类岗位分值分布
  10. clone,Duplicate复制target XCode iOS
  11. C# BackgroundWorker使用讲解
  12. vue3小兔鲜儿项目文档,视频
  13. Linux移植libmodbus
  14. 软件测试是不是IT行业最容易学的 ,大概需要多长时间,就业前景好吗?
  15. java 汇率换算_原生JS实现简单的汇率转换问题
  16. Tencent/tencent-ml-images Readme说明
  17. The Bean Validation API is on the classpath but no implementation could be found
  18. 如何用Pytorch读取自己的数据集
  19. 信用卡到底有什么好处?教你四个技巧拥有大额信用卡
  20. 【研一小白的白话理解】pytorch-CycleGAN-and-pix2pix

热门文章

  1. Subversion 安装文件及操作手册
  2. JDBC操作数据库的问题总结
  3. PCIE的DMA和PIO介绍
  4. IO OutputStreamWriter和InputStreamReader
  5. 訪问可能没有定义的data (通过static类型flash.net:FileReference引用)
  6. NTP服务器搭建教程
  7. EasyUI 1.4.4 DataGrid(大数据量) bufferview滚动时不加载下一页数据解决方案
  8. IE应用商店与.net WPF浏览器应用
  9. html给td内容加删除线,【原创】tr上加删除线-且满足一个页面多表格
  10. 【python入门到实践1】简介和环境搭建