为什么设置系统字体,应用中字体会根据系统字体改变

设置系统字体显示大小后,应用中的字体也根据也跟随系统设置而变化,这样是不是之前写好的整个布局就有可能乱了。

拿TextView源码看下面setTextSize源码看下设置字体细节

/**
*  unit 设置字体的单位 比如 sp,px,dp等等
*  size  字体大小
**/
public void setTextSize(int unit, float size) {if (!isAutoSizeEnabled()) {setTextSizeInternal(unit, size, true /* shouldRequestLayout */);}}

继续往下看

    private void setTextSizeInternal(int unit, float size, boolean shouldRequestLayout) {Context c = getContext();Resources r;// 获取Resources 对象,当前View没有就获取系统的一般当前view都会有if (c == null) {r = Resources.getSystem();} else {r = c.getResources();}// 将设置的字体大小根据 unit 单位和DisplayMetrics进行换算setRawTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics()),shouldRequestLayout);}

继续看下TypedValue.applyDimension() 如何计算字体大小的

   // 字体换算方法public static float applyDimension(int unit, float value,DisplayMetrics metrics){switch (unit) {case COMPLEX_UNIT_PX:return value;case COMPLEX_UNIT_DIP:return value * metrics.density;case COMPLEX_UNIT_SP:return value * metrics.scaledDensity;case COMPLEX_UNIT_PT:return value * metrics.xdpi * (1.0f/72);case COMPLEX_UNIT_IN:return value * metrics.xdpi;case COMPLEX_UNIT_MM:return value * metrics.xdpi * (1.0f/25.4f);}return 0;}

可以看出,根据不同unit计算出来的字体大小不一样,px是不需要就算,,dip是根据density 去计算,sp是根据 scaledDensity计算字体大小,pt是根据xdpi 和一个指定指数计算等等。当改变系统现实大小的时候,参与字体计算的值只要有变化都会改变字体大小。

通过改变系统字体大小,打log看以DisplayMetrics中的值只有scaledDensity 这个值有变化 (可以参考) 所以只要我们在系统字体改变的时候,控制这个值不要改变就可以了,那这个值是在那里赋值?通过一顿瞎点,点到了ResourceImpl这个类里边的updateConfiguration
方法,并且在方法中看到了这个字段的赋值

 public void updateConfiguration(Configuration config, DisplayMetrics metrics,CompatibilityInfo compat) {//.....// Protect against an unset fontScale.mMetrics.scaledDensity = mMetrics.density *(mConfiguration.fontScale != 0 ? mConfiguration.fontScale : 1.0f);// .....}

原来scaledDensity 是fontScale和density计算得来的,density 改变系统字体是不会变化的,那就是fontScale这玩意导致的,那这玩意是那的,通过一顿点击发现是Configuration类的一个public 字段,那这fontScale这个字段系统是什么时候设置的呢?一顿点和排查最后找到了ActivityManageService中的updateFontScaleIfNeeded的方法

private void updateFontScaleIfNeeded(@UserIdInt int userId) {//.....synchronized (this) {if (getGlobalConfiguration().fontScale == scaleFactor) {return;}//.....
}

再看下这个方法是哪里调用的,又是一通乱点发现是在ActivityManageService中的一个内部类FontScaleSettingObserver
中的一个onChange方法中调用的,

 private final class FontScaleSettingObserver extends ContentObserver {@Overridepublic void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {if (mFontScaleUri.equals(uri)) {updateFontScaleIfNeeded(userId);} else if (mHideErrorDialogsUri.equals(uri)) {synchronized (ActivityManagerService.this) {updateShouldShowDialogsLocked(getGlobalConfiguration());}}}}

我猜这个肯定是一个观察者模式,观察到系统配置有相关变化,随后去设置一系列的值,那我们也可以手动的改变这个fontScale值为基准的,不让其随着系统改变而改变、
网上找了段代码,在activity中添加就可以了,源码也不知道分析有误没,如果有误欢迎来提

 @Overridepublic Resources getResources() {Resources resources = super.getResources();Configuration configuration =new Configuration();configuration.setToDefaults();resources.updateConfiguration(configuration,resources.getDisplayMetrics());return resources;}

Android 为什么设置系统字体,应用字体会根据系统字体改变?相关推荐

  1. 调度录音系统服务器应保持,调度录音系统服务器应保持频率同步。()

    相关题目与解析 无线系统录音服务器,录音记录管理主要包括(). 无线系统录音服务器当录音记录不断增加达到磁盘容量90%时,系统将自动执行删除记录,直到磁盘剩余容量在预警值范围内.() 音响系统与消防报 ...

  2. 系统工程师应具备的技能

    系统工程师应具备的技能 系统工程师应具备的技能 总结 在网上搜了一哈,系统工程师招聘的要求,如下图: 本人在这里学习linux源码分析,提供了如下两个链接: 体验课(Linux内核源码/内存调优/文件 ...

  3. iOS和android h5字体差异,关于移动hybrid开发中H5页面的字体应与系统保持一致的问题...

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 0.问题来源 在移动hybrid开发,也就是说,部分页面会使用html+css+javascript技术来制作,例如个人 ...

  4. android webview 字体 系统字体大小,【转】android webview设置内容的字体大小

    Enum for specifying the text size. SMALLEST is 50% SMALLER is 75% NORMAL is 100% LARGER is 150% LARG ...

  5. android TextView设置字体颜色

    今天,简单讲讲如何设置TextView的字体颜色. 其实很简单,不过之前忘记了,所以还是记录,总结一下. TextView的字体设置方法: 1.直接通过配置文件设置 2.在Activity类中进行设置 ...

  6. Android TextView 设置文字背景色或文字颜色,字体阴影,字体样式

          String str="这是设置TextView部分文字背景颜色和前景颜色的demo!";         int bstart=str.indexOf("背 ...

  7. 如何设置app字体跟随系统_Android 应用全局字体调节或禁止随系统字体大小更改...

    禁止跟随系统字体大小调节 如果要像微信一样,所有字体都不允许随系统调节而发生大小变化,要怎么办呢?利用Android的Configuration类中的fontScale属性,其默认值为1,会随系统调节 ...

  8. android webview设置行间距,通过webview设置字体的行间距

    有时候可用 UIWebView 代替 UITextView,解决行间距问题 2011-12-10 - Unmi 我们在使用 UILabel 或是 UITextView 时,如果文字出现了换行,目前我还 ...

  9. android+设置字体行高,android textview设置字体的行距和字间距

    android textview设置字体的行距和字间距 字间距 textView有一个属性android:textScaleX是调节字间距的,它的值是一个float型.查看源代码,默认textView ...

最新文章

  1. 移动应用开发的六大编程语言
  2. php手册常用的函数
  3. TCP三次握手与四次挥手
  4. Android chromium 1
  5. 【Flutter】Flutter Gallery 官方示例简介 ( 项目简介 | 工程构建 )
  6. 华为手机双卡有android,华为Mate 40系列手机入网:双卡5G+安卓系统
  7. 独立开发人员的自由之路 ——1
  8. access和python哪个难学-access和python学哪个好一点
  9. C++primer第十一章 关联容器 11.3关联容器操作 11.4 无序容器
  10. android+apk启动过程,Android Apk的运行过程(一)—— Activity启动与页面事件传递...
  11. python自制有声小说
  12. 为什么 Rust 连续 4 年获「最受喜爱编程语言」?
  13. 【转载】 C#中使用int.TryParse方法将字符串转换为整型Int类型
  14. MFC_选择目录对话框_选择文件对话框_指定目录遍历文件
  15. 大数据技术在网络安全分析的作用
  16. HDOJ--1269--迷宫城堡
  17. 在cs页面获取input的值方法
  18. ubuntu20.04安装qq音乐并解决闪退问题
  19. 心理学与生活 - 发展与教育
  20. 如何排查内存飙升的情况

热门文章

  1. Java中的方法重载。
  2. 国内光电线缆商开博尔正式推出纯光纤HDMI线支持8K
  3. 华为mate20保时捷鸿蒙,抢到就是赚!华为Mate20RS保时捷设计明日开售
  4. 脑科学实验-割裂脑研究
  5. Logstash【从无到有从有到无】【L24】贡献了Java插件
  6. 带你了解裸纤、专线、SDH、MSTP、MSTP+、OTN、PTN、IP-RAN的区别
  7. 华为eNSP: OSPF+RIP实验
  8. 什么是 Skia ?
  9. 观点:2009年协同办公软件市场谁称王?
  10. 基于FPGA的线阵CCD图像测量系统研究——笔记