android架构师之路——修改app字体
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);}
}
全局修改字体
- 全局修改原理,可以参考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;}});}
总结
修改字体大致流程就是这样,总共有四种方式
- 通过textview的android:typeface="normal"设置字体
- 通过textview的android:fontFamily="serif"设置字体
- 通过加载fonts/specified.ttf文件,调用setTypeface设置
- 在BaseActivity统一设置字体,需要每一个activity集成这个BaseActivity
- 在application里面通过registerActivityLifecycleCallbacks注册ActivityLifecycleCallbacks,然后在onActivityCreated方法中统一修改字体
这五种方式,都在demo中加以体现了,第四种与第五种都是全局修改字体,任选其一
demo下载
android架构师之路——修改app字体相关推荐
- Android架构师之路
很多Android的小伙伴在做了多年的开发之后,始终搞不清楚达到Android架构师需要何种技能,我们对比着Android高级工程师来说明. 我们先来看一下Android高级工程师的招聘要求 职位描述 ...
- android仿QQ优雅的修改App字体大小
最近公司有需求需要在App里提供修改应用字体大小的功能,网上查了下资料,感觉都不是和理想,后决定自己实现功能. 实现原理 根据Activity的主题动态修改,在主题中添加自定义的字体大小属性,满足不同 ...
- Android感应检测Sensor(简单介绍),Android架构师之路
实现以下两个SensorEventListener方法来监听,并取得感应检测Sensor状态: //在感应检测到Sensor的精密度有变化时被调用到. public void onAccuracyCh ...
- android 链式结构,Android 架构师之路10 设计模式之责任链模式
1. 责任链模式概念 1.1 介绍 客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁是具体的处理对象.这样就实现了请求者和接受者之间的解耦,并且在客户端可以实现动态的组合职责 ...
- Android从程序员到架构师之路3
本文学习自高焕堂老师的Android从程序员到架构师之路系列教学视频 40 - 认识线程(Thread)模式a 1. 线程(Thread)概念 所谓线程(Thread) 是指一串连续的执行动作,以达成 ...
- 成为一名合格Android架构师,移动APP开发框架盘点,面试资料分享
缘起 经过近十年的发展,Android技术优化日新月异,如今Android 10.0 已经发布,Android系统性能也已经非常流畅,可以在体验上完全媲美iOS.到了各大厂商手里,改源码.自定义系统, ...
- python爬虫架构师之路_一位资深 架构师大牛给予Java技术提升的学习路线建议
一位资深 架构师大牛给予Java技术提升的学习路线建议 对于工作多年的程序员而言,日后的职业发展无非是继续专精技术.转型管理和晋升架构师三种选择. 架构师在一家公司有多重要.优秀架构师需要具备怎样的素 ...
- 阿里Android架构师面试就这?我上我也行!
一.牛*初现 刚踏进大学入门Android开发的时候,对架构师这个词并没有太多的概念,就觉得肯定很牛*,感觉只要随着时间的沉淀就必然会"进化"成架构师. 后来开始写代码,从Java ...
- 如何成为一名Android架构师,乃至高级架构师,文末有路线图
很多Android的小伙伴在做了多年的开发之后,始终搞不清楚达到Android架构师需要何种技能,我们对比着Android高级工程师来说明. 我们先来看一下Android高级工程师的招聘要求 职位描述 ...
最新文章
- classpath路径(转)
- 浅谈EntityFramework框架的使用
- oracle 存储过程 stored procedure 查询一条记录或多条记录
- python语言使用什么语句实现上下文管理协议_Python 上下文管理器
- dedecms织梦模板|绿色仿下载吧网站织梦dede模板源码
- Vue实现跑马灯效果以及封装为组件发布
- 云计算产业迎利好 未来五年信息化发展蓝图公布
- 《Cacti实战》——2.3 Cacti的安装与配置
- 3D数学基础:矩阵的几何解释
- 单片机C语言入门自学指南(前期准备)
- SPSS统计分析常用知识点
- VS | 设置头文件包含目录(无法打开包括文件,No such file or directory的解决)
- PDF.js使用教程
- ensp模拟器使用USG6000V防火墙模拟搭建点到点的IPSec 隧道(web网页版)
- App为了漂亮脸蛋也要美颜,Theme 与 Style 的使用,附一键变装 demo
- 如何远程连接另外一台电脑
- 比例导引 matlab,比例导引法Matlab仿真.docx
- 数码时代的阅读,选择kindle还是ipad?
- pdfh5使用及不显示pdf文件原因
- 【智慧社区】智能路灯系统,打造技术与应用领先的社区路灯