如何正确设置动态TextView的textSize

简介: 如何正确设置动态TextView的textSize

今天测试测出了一个问题,在高分辨率下TextView的显示没问题,在低分辨率出现了字体特别的小,也就是没适配好。


image.png

左边的是 768 * 1028 分辨率的机子,右边的是 1440 * 2560 分辨率


推荐新闻部分是动态设置的TextView,出现了适配问题,然后来看看我的代码


第一次尝试

TextView tv = new TextView(mContext);
    tv.setTextSize(PixelUtils.sp2px(getContext(),4));
复制代码


这么写的思路是,屏幕都是以px为单位,文字大小用sp,我估摸着用sp的文字大小转换成px设置到屏幕上,刚好适配,方案失败。


第二次尝试

TextView tv = new TextView(mContext);
    tv.setTextSize(getResources().getDimensionPixelSize(R.dimen.sp_14));
复制代码


转换有问题是吧,那我不转换,我去dimens文件里面去取这个sp值,然后设置到界面上。


image.png

我靠,不至于吧,怎么变这么大,xml写14sp的时候可是稳稳的


第三次尝试

TextView tv = new TextView(mContext);
    tv.setTextSize(13);
复制代码


实在无力了,随便写了算了,碰碰运气,擦,居然可以,牛逼。


image.png


好奇的我就点进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,看参数名字是跟sp有关系


然后看setTextSize(int unit,float size)方法,判断了下当前有没有context上下文,然后拿到资源Resources,然后看下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,来分别计算出不同单位对应的像素值是多少,跟我们的工具类PixelUtils.sp2px计算方法一模一样,那些找像素转换还在百度和github的,这不都是现成的嘛,不仅仅有dp、sp的,还有pt、in和mm


然后我们回到setTextSize(float size)方法,默认传递的

TypedValue.COMPLEX_UNIT_SP,这一地方就是,你设置的size,我会帮你当做sp单位,然后转换成px设置到屏幕上去,和我第一次尝试的想法一样,但是第一次为啥会失败呢?

我们想想,我在调用PixelUtils.sp2px的时候进行了一次计算,这里计算的结果我本来是想当做px用的,没想到计算出来的结果直接被当做sp来用,然后通过setTextSize又进行了一次sp2px的计算,这个地方错就错在了第一次计算,因为第一次不同分辨率下计算出来的sp2px是不一样的,这个时候设置到屏幕上面去,肯定是完美的,但是,setTextSize对我们的计算结果又进行了一次sp2px,导致完美结果出错,这就是我们为啥出错了的原因。

第二次尝试出错就不说了,通过Resource拿到的dimen大小,最终会被转换成px单位,就相当于sp2px(14),px都变得老老大了,然后当做sp一样的去设置,肯定不对。


总结


1、这下知道了为啥TextView要用sp做单位了,就连setTextSize方法默认都是以sp来计算文字大小的。

2、不要相信群里那些说不看源码的,说什么面试看源码就是装逼耍流氓的,告诉你,不看的话,你就是完蛋,问题都不知道怎么解决

3、完毕,经理催我做项目了

目录
相关文章
|
Android开发
解决 Android Studio 日志乱码
解决 Android Studio 日志乱码
1059 0
解决 Android Studio 日志乱码
|
4月前
|
存储 缓存 算法
xv6 启动理论部分
xv6 启动理论部分
98 2
|
10月前
|
程序员 Android开发 开发者
Aab(Android App Bundle)测试与安装
Aab(Android App Bundle)测试与安装
802 0
|
Android开发
Android button 点击跳转页面
Android button 点击跳转页面
Android button 点击跳转页面
|
8月前
|
消息中间件 安全 Java
Java中的异步编程方案总结
Java中的异步编程是一种能够提高程序性能和响应速度的技术。它通过将耗时的操作放在单独的线程中,让主线程继续执行其他任务,从而实现并发处理和异步执行。在Java中,异步编程常用的方式有多线程、Future和CompletableFuture等。在实际应用中,异步编程可以优化网络请求、数据库操作等IO密集型任务的性能,提高程序的响应速度和吞吐量。虽然异步编程可以带来许多好处,但同时也涉及到一些问题,比如线程安全、回调地狱等。因此,在使用异步编程时需要注意合理地设计和管理线程,确保程序的正确性和可维护性。
161 1
Java中的异步编程方案总结
|
IDE 开发工具 Android开发
Gradle升级,Error:Connection timed out: connect. If you are behind an HTTP proxy, please configure
Gradle升级,Error:Connection timed out: connect. If you are behind an HTTP proxy, please configure
3594 0
Gradle升级,Error:Connection timed out: connect. If you are behind an HTTP proxy, please configure
|
缓存 JSON ARouter
Android开源系列-组件化框架Arouter-(一)使用方式详解
最近组里需要进行**组件化框架**的改造,用到了`Arouter`这个开源框架,为了更好的对项目进行改造,笔者花了一些时间去了解了下`Arouter
|
12月前
|
缓存 Java 机器人
Android C++系列:JNI常见问题
正常情况我们在方法里面申请的local reference会在方法执行完后自动释放,所以一直没有太在意local reference的释放,结果在一个线程的looper方法中有两个jstring使用完一直没释放,导致交互多轮后泄露崩溃。
361 0
|
XML Android开发 uml
Android 补间动画及动画组合AnimationSet常用方法整理
`Android`常用的四种补间动画分别为`RotateAnimation`、`ScaleAnimation`、`TranslateAnimation`、`AlphaAnimation`,他们的父类为`Animation`
|
JavaScript Java Android开发
android studio中文乱码各种情况的解决办法
android studio中文乱码各种情况的解决办法
529 0
android studio中文乱码各种情况的解决办法