【Android】 字体适配——不跟随系统字体大小、动态设置字体大小之坑
目录
TextView.setTextSize(); 适配问题起源
TypedValue.applyDimension(unit, size, r.getDisplayMetrics())
安卓API源码自带的像素转换工具
解决问题
动态设置TextSize适配
不跟随系统设置字体大小适配
TextView.setTextSize(); 适配问题起源
@android.view.RemotableViewMethod public void setTextSize(float size) { setTextSize(TypedValue.COMPLEX_UNIT_SP, size); } 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())); } private void setRawTextSize(float size) { if (size != mTextPaint.getTextSize()) { mTextPaint.setTextSize(size); if (mLayout != null) { nullLayouts(); requestLayout(); invalidate(); } } }
setTextSize(float size)最终调用的是setTextSize(int unit,float size)方法,只是设置了一个默认参数TypedValue.COMPLEX_UNIT_SP,也就是调用setTextSize(float size)方法会默认转换为sp单位。
TypedValue.applyDimension(unit, size, r.getDisplayMetrics())
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,来分别计算出不同单位对应的像素值是多少。
动态设置字体不适配设备的原因:sp单位会跟随系统字体大小变化而变化,每台设备的分辨率不同,这就导致了为什么有些设备会出现字体很大或很小的问题。
DisplayMetrics信息:https://blog.csdn.net/weixin_36194487/article/details/80404044
安卓API源码自带的像素转换工具
dp转px方法
public int dp2px(Context context, float dpValue){return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());}
其它转换方法根据源码封装。
解决问题
动态设置TextSize适配
TextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(context, sizeValue));//或者直接TextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, sizeValue);
根据上面的源码,转换后的值会被当作px值,dp是与像素无关的单位, 使用 dp2px() 方法 将dp值转换为px,这样在每台设备上基本大小一致
不跟随系统设置字体大小适配
方法1.
直接设置字体为DP单位
//XML字体单位直接设置为DP//代码TextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, sizeValue);
(不想改变SP单位怎么解决?)
方法2.
因为 scaledDensity = density * fontScale。其中fontScale代表用户设定的Android设备字体缩放比例,默认为1.0。也就是说,当用户没有改变Android设备的字体缩放比例时,sp、dp的换算是相同的。
在Activity、Application、重写getResources()方法
@Overridepublic Resources getResources(){Resources resources = super.getResources();if (resources != null && resources.getConfiguration().fontScale != 1.0f) {Configuration configuration = resources.getConfiguration();configuration.fontScale = 1.0f;resources.updateConfiguration(configuration, resources.getDisplayMetrics());}return resources;}
自定义MyApplication继承自Application记得在清单文件标签内用属性 android:name="包名.路径.MyApplication" 引用。
更多相关文章
- android studio引用java8后编译报错解决方法
- ContentResolver query 特殊条件查询: in,like
- Android-Activity介绍
- Android(安卓)实现轮播图效果(二) 底部圆点布局实现
- Android(安卓)WebService
- Android(安卓)MediaPlayer
- [置顶] Android(安卓)怎么退出整个应用程序?__以及__按键事件捕获
- Android(安卓)WebView封装及定制js的alert,confirm和prompt对话
- Android(安卓)设置屏幕不待机