Android全局替换字体
一、概述
ps:上次说的LayoutInflaterCompat.setFactory2来全局替换字体的方案,在使用过程中发现存在缺陷。今天补充一个优化版方案
LayoutInflaterCompat.setFactory2这个方案的好处是比较方便,全局替换,也可以做一些个性化的操作,如:修改字体填充、随意更改样式,可以就不同控件的字体单独区分设置,比较灵活。
但是:其会导致布局的加载速度变慢。布局稍微复杂一点,这个加载速度是难以忍受的。
今天另一种方案来替换全局字体:
通过配置应用主题,全局替换默认字体
步骤:
1.在res文件夹下新建一个font文件夹,然后把你需要使用的字体库放进去
2.在Application中的theme中应用你的主体
<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <!-- 在这里设置全局字体 --> <item name="android:fontFamily">@font/source_han_sans_cn_bold</item> <item name="android:includeFontPadding">false</item> </style>
3.搞定
由于业务需要,各端之间统一字体(Android、IOS、PC、网页)。所以android也需要替换成特定的字体。
以后有可能还会增加其他的字体。
方案:
使用LayoutInflaterCompat.setFactory2来全局替换字体。这样做的好处是可以一次性的替换大部分的字体。剩余的个性化字体再单独适配。
这样效率最高,最省时间。
二、代码示例
1.在BaseActivity中加入
//全局字体设置
LayoutInflaterCompat.setFactory2(getLayoutInflater(), getLayoutFactory2());
2.自定义一个类继承LayoutInflater.Factory2接口
private LayoutInflater.Factory2 getLayoutFactory2() { return new TextViewFontProxy(); } private class TextViewFontProxy implements LayoutInflater.Factory2 { @Nullable @Override public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) { return getProxyView(name, context, attrs); } @Nullable @Override public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) { return getProxyView(name, context, attrs); } } private View getProxyView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs){ switch(name){ case "TextView": return new SiYuanBlackBodyTextView(context, attrs); case "EditText": return new SiYuanBlackBodyEditText(context, attrs); } return null; }
3.自定义一个字体类
/** * 思源黑体,自定义字体 */ class SiYuanBlackBodyTextView : AppCompatTextView { private val fontPath = "font/source_han_sans_cn_bold.otf" constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super( context, attrs, defStyleAttr ) { setTypeFace() } constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { setTypeFace() } constructor(context: Context) : super(context) { setTypeFace() } private fun setTypeFace() { try { includeFontPadding = false val typeface = Typeface.createFromAsset(context.assets, fontPath) setTypeface(typeface) } catch (ignored: Throwable) { } } }
三、问题补充
这里需要注意一下字体的上下填充,思源合体默认上下填充是非常大的。如果不做适配直接回影响全局的布局。
这里在设置字体的时候加入includeFontPadding = false即可。作用:去掉字体上下填充
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探