Android系统字体大小如何影响app的字体大小?
2016-12-25 00:54
666 查看
在Android应用开发过程中,一定会碰到本来完美的布局,在系统字体大小设置【最大】时变成一团浆糊。解决办法网上也有很多,但是分析原理的却几乎没看到。博主在碰到问题的第一时间也是直接用了网上的方法,即在BaseActivity中重写getResources方法如下
这个方法是有效的。
但是作为开发人员必须懂得举一反三,而要举一反三就必须要“知其所以然”,于是博主就去探寻了一番,才有了此篇文章。
我们拿TextView来举例,看看它的setTextSize方法
看一眼代码,至少可以确定一件事情:设置的字体大小在内部做了计算和变换。
没错,就是这个applyDimension方法干的好事!!
我们跟进去看看先:
事实一目了然,我们设置进去的value值,这个方法返回的是value*metrics.scaledDensity 问题肯定出在scaledDensity这个属性身上!!!
好了,字体大小的设置到此结束。
然后是具体实现的方法:
相信大家都看到了,mMetrics.scaledDensity的值其实是受mConfiguration.fontScale影响的。那么我们的研究对象又一次转变了,变成了fontScale。
此时,我们对照一下,网上的解决系统字体大小影响的代码片段
看来路子是走对了,这里也是对Configuration进行了设置,并且还调用了updateConfiguration方法。
并且我还告诉你,这里的config.setToDefaults()方法内部第一句代码就是fontScale=1。
那么分析到这里,我们基本可以推测:如果修改系统的字体大小,fontScale肯定会改变!
博主的是锤子T1,打印出来的结果是
标准 —– fontScale = 1.0
较大 —– fontScale = 1.1
最大 —– fontScale = 1.4
到此为止,我们还是不能百分之百确定问题一定是因为fontScale值的变化引起的。
我们还需要做最后一件事情——通过修改fontScale值来修复字体大小的问题!
跟网上的解决办法一样,重载Activity的getResources方法如下:
经博主测试,问题完美解决!!并且,对比网上的解决办法,我们并没有新建一个Configuration对象,从性能角度上说,这个办法更优。
@Override public Resources getResources() { Resources res = super.getResources(); Configuration config=new Configuration(); config.setToDefaults(); res.updateConfiguration(config,res.getDisplayMetrics()); return res; }
这个方法是有效的。
但是作为开发人员必须懂得举一反三,而要举一反三就必须要“知其所以然”,于是博主就去探寻了一番,才有了此篇文章。
1.字体大小如何设置
这个简单,就拿TextView来说,设置字体大小调用setTextSize方法就行了。如果你直接以px为单位设置字体大小,那么应用字体大小是绝对不会被系统字体所影响的,但是绝大多数时候,我们用的单位都是sp,sp是什么?sp = scaled pixel 即缩放了的像素值。而如果用了sp就一定会受系统字体大小的影响。我们拿TextView来举例,看看它的setTextSize方法
public void setTextSize(int unit, float size) { Context c = getContext(); Resources r; if (c == null) r = Resources.getSystem(); else r = c.getResources(); setRawTextSize(TypedValue.applyDimension( unit, size, r.getDisplayMetrics())); }
看一眼代码,至少可以确定一件事情:设置的字体大小在内部做了计算和变换。
没错,就是这个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; }
事实一目了然,我们设置进去的value值,这个方法返回的是value*metrics.scaledDensity 问题肯定出在scaledDensity这个属性身上!!!
好了,字体大小的设置到此结束。
2. scaledDensity真面目
根据网上提供的办法,我们知道字体大小的影响跟Resources有关(具体原因待分析)。于是博主在Resources.java源码中进行了查找,发现了一个重要的方法public void updateConfiguration(Configuration config, DisplayMetrics metrics) { updateConfiguration(config, metrics, null); }
然后是具体实现的方法:
public void updateConfiguration(Configuration config, DisplayMetrics metrics, CompatibilityInfo compat) { synchronized (mAccessLock) { ... 省略代码 ... mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale; ... 省略代码 ... } synchronized (sSync) { if (mPluralRule != null) { mPluralRule = NativePluralRules.forLocale(config.locale); } } }
相信大家都看到了,mMetrics.scaledDensity的值其实是受mConfiguration.fontScale影响的。那么我们的研究对象又一次转变了,变成了fontScale。
此时,我们对照一下,网上的解决系统字体大小影响的代码片段
@Override public Resources getResources() { Resources res = super.getResources(); Configuration config=new Configuration(); config.setToDefaults(); res.updateConfiguration(config,res.getDisplayMetrics()); return res; }
看来路子是走对了,这里也是对Configuration进行了设置,并且还调用了updateConfiguration方法。
并且我还告诉你,这里的config.setToDefaults()方法内部第一句代码就是fontScale=1。
那么分析到这里,我们基本可以推测:如果修改系统的字体大小,fontScale肯定会改变!
3. 最终解决
首先,推测是需要验证的。我们可以编写一个demo,在MainActivity的onCreate方法中打印fontScale值Log.d("Javine","fontScale = "+getResources().getConfiguration().fontScale);
博主的是锤子T1,打印出来的结果是
标准 —– fontScale = 1.0
较大 —– fontScale = 1.1
最大 —– fontScale = 1.4
到此为止,我们还是不能百分之百确定问题一定是因为fontScale值的变化引起的。
我们还需要做最后一件事情——通过修改fontScale值来修复字体大小的问题!
跟网上的解决办法一样,重载Activity的getResources方法如下:
@Override public Resources getResources() { //获取到resources对象 Resources res = super.getResources(); //修改configuration的fontScale属性 res.getConfiguration().fontScale = 1; //将修改后的值更新到metrics.scaledDensity属性上 res.updateConfiguration(null,null); return res; }
经博主测试,问题完美解决!!并且,对比网上的解决办法,我们并没有新建一个Configuration对象,从性能角度上说,这个办法更优。
相关文章推荐
- 如何设置android app 的字体大小不受系统字体大小改变的影响
- 如何设置android app 的字体大小不受系统字体大小改变的影响
- Android App字体不受系统字体大小影响
- Android 系统字体大小影响UI显示问题
- Android APP字体大小跟随系统设置
- 让APP字体不受系统字体大小影响
- Android 如何获取系统字体大小
- Android 如何修改系统默认字体大小
- Android重写getResources规避用户调整系统字体大小影响Android屏幕适配
- 关于Android切换系统字体大小和字体样式导致App崩溃或者界面错乱的问题
- 如何修改android系统字体大小
- Android 中应用的字体大小不受系统字体大小影响
- [Android] 字体使用dp单位避免设置系统字体大小对排版的影响
- Android中设置APP应用字体不缩放,文字不随系统字体大小变化
- 安卓设置更改系统字体大小,影响App展示
- 设置Android app的字体不随系统全局字体大小的变动而变动
- [Android] 字体使用dp单位避免设置系统字体大小对排版的影响
- 关于android系统Dialog如何设置字体大小
- Android 字体使用dp单位避免设置系统字体大小对排版的影响
- <转>Android APP字体大小,不随系统的字体大小变化而变化的方法