前言

近期项目需要在我们的APP中使用指定的字体库。经过搜集资料,研读源码,和别人探讨请教,最终产出了一些比较好的方案。不敢专享,写成文章分享出来,希望对大家的实际开发工作有所帮助。喜欢探讨Android开发技术的同学可以加学习小组QQ群: 193765960。

本文只总结了较优方案,其他诸如自定义textView类,遍历layout_root_view这样的方案,作者认为限制较大,使用麻烦,就不在这里介绍了,感兴趣的朋友请自行百度。

Android字体机制介绍

关键类:

Typeface:

字体类,定义了字体类型到字体库的映射关系,Android有DEFAULT, MONOSPACE, SERIF, SANS_SERIF几种字体,根据各自的NORMAL(常规),BOLD(加粗),ITALIC(倾斜),BOLD_ITALIC(加粗倾斜)等几种样式,总共可以映射到至少16种字体库。

TextAppearance:

字体外观类,定义了字体的外观比如,typeface,textsize,textcolor等外观属性。

TextView的字体显示机制

先看一下TextView的构造方法:

public TextView(Context context);

public TextView(Context context, @Nullable AttributeSet attrs);

public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr);

public TextView(

Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes);

AttributeSet:xml中设置的属性

defStyleAttr:系统默认的属性

defStyleRes:系统默认的样式,这个是我们需要注意的参数哈

Textview的字体设置逻辑:

1)查看xml中是否设置了TextAppearance属性,如果设置了就判断外观中是否设置了字体。否则就执行第二步。

2)查看xml中是否设置了Typeface属性,指明了字体。否则执行第三步

3)使用系统的默认样式:defStyleRes

所以,假如我们的xml中对字体没有做设置,要是想要修改字体又不想修改xml,那么我们就要想其他办法了。

我最终的方案(方案一)是在APP的theme中去设置修改系统的默认样式(最终走到这个思路上是经过了比较酸爽的经过的,就不在这里细说了)。

方案一(底层方案):通过反射机制,修改Typeface类的字体库引用

第一步:通过反射机制修改Typeface字体指向的字体库到我们的字体库。

定义修改字体库的方法类(示例):

import java.lang.reflect.Field;

import android.content.Context;

import android.graphics.Typeface;

public final class FontsUtils {

public static void setDefaultFont(Context context,

String staticTypefaceFieldName, String fontAssetName) {

final Typeface regular = Typeface.createFromAsset(context.getAssets(),

fontAssetName);

replaceFont(staticTypefaceFieldName, regular);

}

protected static void replaceFont(String staticTypefaceFieldName,

final Typeface newTypeface) {

try {

final Field staticField = Typeface.class

.getDeclaredField(staticTypefaceFieldName);

staticField.setAccessible(true);

staticField.set(null, newTypeface);

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

}

在工程assets目录下新建fonts文件夹,把我们需要的字库放在里面,比如:FZLTHJW.TTF

在MyApplication.oncreate()中调用修改字体库:

FontsUtils.setDefaultFont(this, "DEFAULT", "fonts/FZLTHJW.TTF");

FontsUtils.setDefaultFont(this, "MONOSPACE", "fonts/FZLTHJW.TTF");

FontsUtils.setDefaultFont(this, "SERIF", "fonts/FZLTHJW.TTF");

FontsUtils.setDefaultFont(this, "SANS_SERIF", "fonts/FZLTHJW.TTF");

第二步:修改APP theme的默认属性。

@style/FontTextviewstyle

@style/FontButtonstyle

@style/FontEditTextstyle

@style/FontradioButtonstyle

@style/FontTextAppearance

@style/FontTextAppearance

@style/FontTextAppearance

@style/FontTextAppearance

monospace

总结:

优点:

不用修改xml,没有为每个activity创建字体的实例。

除了常见的控件外,对Material Design的新控件也有作业

缺陷:

对于alertDialog还没有实现style的默认适配

因为是修改的底层逻辑,相较于方案二,稍复杂。

方案二(顶层方案):自定义布局加载器,在加载layout_xml时对view tree的 view做字体的逻辑处理

使用:如下方代码所示,在oncreatview的回调中,对view做类型判断,设置view的字体。

优点:该方案代码逻辑清晰,使用简单,几行代码就可以搞定问题,不用修改xml等。

缺陷:

在一些第三方的控件或者自定义控件上可能使用会有限制,如果控件没有提供修改控件字体的接口的话(待验证)

需要注意的是,对于Material Design的android.support.design.widget.TextInputLayout,android.support.design.widget.TabLayout这样的控件不起作用,需要对这种类型设置*textAppearance这样的属性。

private void replaceFont() {

final Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/fangzheng.ttf");

LayoutInflaterCompat.setFactory(LayoutInflater.from(this), new LayoutInflaterFactory() {

@Override

public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {

// TODO Auto-generated method stub

AppCompatDelegate delegate = getDelegate();

View view = delegate.createView(parent, name, context, attrs);

if(view != null ){

if(view instanceof TextView){

((TextView)view).setTypeface(typeface);

}else if(view instanceof Button){

((Button)view).setTypeface(typeface);

}else if(view instanceof RadioButton){

((RadioButton)view).setTypeface(typeface);

}

}

return view;

}

});

}

/**

* BaseActivity.java

*/

@Override

protected void onCreate(Bundle savedInstanceState) {

replaceFont();//注意需要在super方法之前调用,否则会报异常

super.onCreate(savedInstanceState);

}

总结:

通过这个方案,其实我们应该学习到一种统一对xml viewTree中某种控件设置某种属性的方法。

举一反三,针对刚才上述的缺陷,我们其实也可以尝试设置textAppearance属性(相较于设置typeface麻烦些),感兴趣的同学可以去试验下。

android app替换字体,Android APP更换字体策略精要相关推荐

  1. Android动态替换dex,Android DexClassLoader动态加载与插件化开发

    参考链接: 一. 基本概念和注意点 1.1 首先需要了解一点:在Android中可以动态加载,但无法像Java中那样方便动态加载jar 原因:Android的虚拟机(Dalvik VM)是不认识Jav ...

  2. Android auto替换导航,Android Auto获得导航、停车等多方面新应用支持

    得益于谷歌的进一步开放, Android Auto 正获得一系列新的应用支持 ,涵盖导航.停车.充电等等.这些应用程序有包括为电动汽车和插电混动汽车的 Chargepoint 和 PlugShare, ...

  3. android9默认字体下载,iFont爱字体 v5.5.9 Android特别版-实用的手机换字体软件

    iFont爱字体 v5.5.9 Android特别版-实用的手机换字体软件 书法字体2015.09.28iFont iFont(爱字体)是安卓平台最强大.最专业的字体软件,精彩字体,随你所换!iFon ...

  4. android 身高体重设计,Android开发--身高体重指数(BIM)计算--设计用户界面--指定输入类型(InputType)...

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2011, 烟台大学计算机学院学生 * All rights reserved. * 文件名称:指定输入类型( ...

  5. android 自动替换资源文件,简单高效的实现Android App全局字体替换

    Android O推出了一项新的功能「Fonts in XML」,借助这项功能,我们能够像使用其他资源文件一样使用字体,比较方便地实现App全局字体的替换. 为了能够在API 14或者以上的设备上使用 ...

  6. android反射替换字体,快速使用反射更换Android全局字体

    问题背景 之前在编写鲤鱼日语时,因为使用了外部的字体,这导致了一个问题就是我的ListView显示的是圆滑的字体,但是其他dialog.Spinner就全都是Android默认字体,这样不统一就会很难 ...

  7. Android禁止app字体大小跟随系统字体大小调节

    Android禁止app字体大小跟随系统字体大小调节 针对字体不随系统应用改变而改变,不然会导致原来的一些布局变化,在Application中重写getResources() @Overridepub ...

  8. 设置Android APP字体不受系统设置字体大小影响

    1. 前言 Android手机系统的设置中,有个小功能,可以全局调整字体大小.这就导致了APP里面的字体也受影响了,字体变小或变大,对原来布局会产生影响,用户体验不好. 2. 解决方案 查了一下资料, ...

  9. android 怎么导入和应用特殊字体在app项目

    随着市面上的app应用越来越丰富,一款性能优越且让人眼前一亮的app也是越来越少了.一款好的app不仅要界面精美而且要符合大众需求. 界面上的字体是让用户第一眼就能感受到开发者心意的直接表现.但是an ...

最新文章

  1. 微信-js sdk invalid signature签名错误 问题解决
  2. AGI:走向通用人工智能的【哲学】之现实世界的虚拟与真实——带你回看1998年的经典影片《The Truman Show》感悟“什么是真实”
  3. 第9章例题 7-2 学生成绩排序
  4. 发送附件时,防止文件名中的中文字符变成乱码
  5. Tensorflow实现MLP
  6. 织梦服务器系统win10,WIN服务器爆破DEDECMS后台目录
  7. linux非root用户搭建docker,linux centos7 非root用户安装源码版docker
  8. 洛谷 P1306 斐波那契公约数
  9. python--关于if __name__==__main__的解释
  10. OFFICE技术讲座:设置调整字间距(kern)后,标点就不压缩
  11. 互联网光环下的新金融群像:运营最重要的是说人话
  12. 黑苹果电池电量补丁_修改DSDT实现电量显示方法【转载】
  13. 跟大家分享一下牛人常用的资源(牛客网 )!
  14. html页面的bug记录:简单记录几个编辑html页面遇到的问题
  15. 万能网页视频下载教程
  16. HTC Vive Pro eye 眼动数据简单获取
  17. 使用XMind编写测试用例
  18. UI/UE设计师修炼指南-CSDN公开课-专题视频课程
  19. matlab设计激光腔,激光原理课程设计--平行平面腔自再现模Fox-Li数值迭代解法及MATLAB实现...
  20. Java第三方接口鉴权(springboot + 腾讯开放平台)

热门文章

  1. 有关Proteus的下载和仿真问题
  2. 红亚太学链之区块链技术深度剖析第8章
  3. 2023年AI语音会议汇总
  4. [css] 解释下什么是PPI和DP?
  5. 小明的故事(二) -- Fiddler超时导致的事故总结
  6. 用计算机来算出情人节,关于情人节的说说短句子 有关情人节的爱情句子
  7. 真心喜欢一个人是种怎样的体验?
  8. 2014年博创杯參赛历程记(转载)
  9. 练习2-3:个性化消息
  10. 极品飞车20ps4服务器位置,极品飞车20官网在哪?中文官网地址一览