android自带的字体

通过 android:typeface="normal" 或者 android:fontFamily="monospace"两种方式来设置字体,两者区别在于android:fontFamily是API16以后增加

具体字体样式可以参考下图

通过ttf自定义字体

在assets下新建一个fonts文件,把字体样式文件放进去

实现代码如下

/*** 自定义字体*/private void setMyFont() {TextView ttfTextView = findViewById(R.id.text_ttf);AssetManager mgr = getAssets();Typeface tf = Typeface.createFromAsset(mgr, "fonts/specified.ttf");ttfTextView.setTypeface(tf);}

批量修改字体

public class CustomTextView extends TextView
{public CustomTextView(Context context, AttributeSet attrs){super(context, attrs);}//重写设置字体方法@Overridepublic void setTypeface(Typeface tf){tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/specified.ttf");super.setTypeface(tf);}
}

全局修改字体

  1. 全局修改原理,可以参考hongyang的博客

我们可以看一下setcontentview的源码,我这里是基于API28

   public void setContentView(@LayoutRes int layoutResID) {this.getDelegate().setContentView(layoutResID);}

进入this.getDelegate().setContentView

    public void setContentView(int resId) {this.ensureSubDecor();ViewGroup contentParent = (ViewGroup)this.mSubDecor.findViewById(16908290);contentParent.removeAllViews();LayoutInflater.from(this.mContext).inflate(resId, contentParent);this.mOriginalWindowCallback.onContentChanged();}

可以看出也是通过LayoutInflater.from(this.mContext).inflate(resId, contentParent);来加载的布局

下面这图,就是LayoutInflater.from(this.mContext).inflate(resId, contentParent)与factory的关系

我们截取最后一段代码

if (mFactory2 != null) {view = mFactory2.onCreateView(parent, name, context, attrs);} else if (mFactory != null) {view = mFactory.onCreateView(name, context, attrs);} else {view = null;}

所以我们可以调用LayoutInflaterCompat.setFactory2设置mFactory2 以达到调用我们重写的onCreateView

      LayoutInflaterCompat.setFactory2(LayoutInflater.from(this), new LayoutInflater.Factory2() {@Overridepublic View onCreateView(View parent, String name, Context context, AttributeSet attrs) {Log.e(TAG,"name= "+name);int n = attrs.getAttributeCount();for (int i = 0; i < n; i++) {Log.d(TAG,attrs.getAttributeName(i) + " , " + attrs.getAttributeValue(i));}return null;}@Overridepublic View onCreateView(String name, Context context, AttributeSet attrs) {return null;}});

可以看到的输出日志

E/MainActivity: name= TextView
D/MainActivity: layout_width , -2
D/MainActivity: layout_height , -2
D/MainActivity: text , serif-monospace 字体
D/MainActivity: fontFamily , serif-monospace

所以我们只需要在这里修改字体,就可以达到统一修改字体的目的,最终代码如下

    /*** 设置整体字体*/private void setTotalTypeFace() {if (typeface == null) {typeface = Typeface.createFromAsset(getAssets(), "fonts/specified.ttf");}LayoutInflater layoutInflater = LayoutInflater.from(this);try {Field mFactorySet = LayoutInflater.class.getDeclaredField("mFactorySet");mFactorySet.setAccessible(true);mFactorySet.setBoolean(layoutInflater, false);} catch (Exception e) {e.printStackTrace();}layoutInflater.setFactory2(new LayoutInflater.Factory2() {@Overridepublic View onCreateView(View parent, String name, Context context, AttributeSet attrs) {Log.e(TAG, "name= " + name);View view = getDelegate().createView(parent, name, context, attrs);//所以这里创建 View,从而修改View属性Log.e(TAG, "view = " + view);if (view instanceof TextView) {((TextView) view).setTypeface(typeface);}int n = attrs.getAttributeCount();for (int i = 0; i < n; i++) {Log.d(TAG, attrs.getAttributeName(i) + " , " + attrs.getAttributeValue(i));}return view;}@Overridepublic View onCreateView(String name, Context context, AttributeSet attrs) {return null;}});}

总结

修改字体大致流程就是这样,总共有四种方式

  1. 通过textview的android:typeface="normal"设置字体
  2. 通过textview的android:fontFamily="serif"设置字体
  3. 通过加载fonts/specified.ttf文件,调用setTypeface设置
  4. 在BaseActivity统一设置字体,需要每一个activity集成这个BaseActivity
  5. 在application里面通过registerActivityLifecycleCallbacks注册ActivityLifecycleCallbacks,然后在onActivityCreated方法中统一修改字体

这五种方式,都在demo中加以体现了,第四种与第五种都是全局修改字体,任选其一

demo下载

android架构师之路——修改app字体相关推荐

  1. Android架构师之路

    很多Android的小伙伴在做了多年的开发之后,始终搞不清楚达到Android架构师需要何种技能,我们对比着Android高级工程师来说明. 我们先来看一下Android高级工程师的招聘要求 职位描述 ...

  2. android仿QQ优雅的修改App字体大小

    最近公司有需求需要在App里提供修改应用字体大小的功能,网上查了下资料,感觉都不是和理想,后决定自己实现功能. 实现原理 根据Activity的主题动态修改,在主题中添加自定义的字体大小属性,满足不同 ...

  3. Android感应检测Sensor(简单介绍),Android架构师之路

    实现以下两个SensorEventListener方法来监听,并取得感应检测Sensor状态: //在感应检测到Sensor的精密度有变化时被调用到. public void onAccuracyCh ...

  4. android 链式结构,Android 架构师之路10 设计模式之责任链模式

    1. 责任链模式概念 1.1 介绍 客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁是具体的处理对象.这样就实现了请求者和接受者之间的解耦,并且在客户端可以实现动态的组合职责 ...

  5. Android从程序员到架构师之路3

    本文学习自高焕堂老师的Android从程序员到架构师之路系列教学视频 40 - 认识线程(Thread)模式a 1. 线程(Thread)概念 所谓线程(Thread) 是指一串连续的执行动作,以达成 ...

  6. 成为一名合格Android架构师,移动APP开发框架盘点,面试资料分享

    缘起 经过近十年的发展,Android技术优化日新月异,如今Android 10.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS.到了各大厂商手里,改源码.自定义系统, ...

  7. python爬虫架构师之路_一位资深 架构师大牛给予Java技术提升的学习路线建议

    一位资深 架构师大牛给予Java技术提升的学习路线建议 对于工作多年的程序员而言,日后的职业发展无非是继续专精技术.转型管理和晋升架构师三种选择. 架构师在一家公司有多重要.优秀架构师需要具备怎样的素 ...

  8. 阿里Android架构师面试就这?我上我也行!

    一.牛*初现 刚踏进大学入门Android开发的时候,对架构师这个词并没有太多的概念,就觉得肯定很牛*,感觉只要随着时间的沉淀就必然会"进化"成架构师. 后来开始写代码,从Java ...

  9. 如何成为一名Android架构师,乃至高级架构师,文末有路线图

    很多Android的小伙伴在做了多年的开发之后,始终搞不清楚达到Android架构师需要何种技能,我们对比着Android高级工程师来说明. 我们先来看一下Android高级工程师的招聘要求 职位描述 ...

最新文章

  1. classpath路径(转)
  2. 浅谈EntityFramework框架的使用
  3. oracle 存储过程 stored procedure 查询一条记录或多条记录
  4. python语言使用什么语句实现上下文管理协议_Python 上下文管理器
  5. dedecms织梦模板|绿色仿下载吧网站织梦dede模板源码
  6. Vue实现跑马灯效果以及封装为组件发布
  7. 云计算产业迎利好 未来五年信息化发展蓝图公布
  8. 《Cacti实战》——2.3 Cacti的安装与配置
  9. 3D数学基础:矩阵的几何解释
  10. 单片机C语言入门自学指南(前期准备)
  11. SPSS统计分析常用知识点
  12. VS | 设置头文件包含目录(无法打开包括文件,No such file or directory的解决)
  13. PDF.js使用教程
  14. ensp模拟器使用USG6000V防火墙模拟搭建点到点的IPSec 隧道(web网页版)
  15. App为了漂亮脸蛋也要美颜,Theme 与 Style 的使用,附一键变装 demo
  16. 如何远程连接另外一台电脑
  17. 比例导引 matlab,比例导引法Matlab仿真.docx
  18. 数码时代的阅读,选择kindle还是ipad?
  19. pdfh5使用及不显示pdf文件原因
  20. 【智慧社区】智能路灯系统,打造技术与应用领先的社区路灯

热门文章

  1. PL/SQL连接Oracle出现的ORA-01034的解决办法
  2. J9数字虚拟论:元宇宙的潜力:一股推动社会进步的力量
  3. X友NC远程命令执行
  4. a15和骁龙8gen2哪个好 a15和骁龙8gen2对比功耗
  5. webpack4生产环境和开发环境的对比
  6. YOLOv3庖丁解牛(三):YOLOv3损失函数
  7. 最新麦芒装饰装修小程序源码Ver3.2.59版+支持三端
  8. pandas读写Excel详解
  9. 也谈析构:析构函数何时被调用
  10. Git LFS是什么?