目录
TextView.setTextSize(); 适配问题起源
TypedValue.applyDimension(unit, size, r.getDisplayMetrics())
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转换的像素也就不同,并且sp单位会跟随系统字体变化而变化,这就导致了为什么有些设备会出现字体很大或很小的问题。
DisplayMetrics信息:https://blog.csdn.net/weixin_36194487/article/details/80404044
总结:
dp转px方法
public int dp2px(Context context, float dpValue){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue, context.getResources().getDisplayMetrics());
}
动态设置TextView大小时在不同分辨率下适配应该这样写:
TextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp2px(context, sizeValue));
//或者直接
TextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, sizeValue);
根据上面的源码,转换后的值会被当作px值,dp是与像素无关的单位, 使用 dp2px() 方法 将dp值转换为px,这样在每台设备上基本大小一致
字体大小单位为SP就会跟随系统字体变化而变化解决:
方法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()方法
@Override
public 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记得在清单文件<application>标签内用属性 android:name="包名.路径.MyApplication" 引用