【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()方法

    @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" 引用。

 

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚妄狼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值