如何正确设置动态TextView的textSize

小鱼儿 2021-04-24 03:09 654阅读 0赞

如何正确设置动态TextView的textSize

Android.jpg

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

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

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

第一次尝试

  1. TextView tv = new TextView(mContext);
  2. tv.setTextSize(PixelUtils.sp2px(getContext(),4));

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

第二次尝试

  1. TextView tv = new TextView(mContext);
  2. tv.setTextSize(getResources().getDimensionPixelSize(R.dimen.sp_14));

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

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

第三次尝试

  1. TextView tv = new TextView(mContext); tv.setTextSize(13);

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


好奇的我就点进setTextSize方法里面看了下源码,这才大悟恍然,先贴源码

  1. @android.view.RemotableViewMethod
  2. public void setTextSize(float size) {
  3. setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
  4. }
  5. public void setTextSize(int unit, float size) {
  6. Context c = getContext();
  7. Resources r;
  8. if (c == null)
  9. r = Resources.getSystem();
  10. else
  11. r = c.getResources();
  12. setRawTextSize(TypedValue.applyDimension(
  13. unit, size, r.getDisplayMetrics()));
  14. }
  15. private void setRawTextSize(float size) {
  16. if (size != mTextPaint.getTextSize()) {
  17. mTextPaint.setTextSize(size);
  18. if (mLayout != null) {
  19. nullLayouts();
  20. requestLayout();
  21. invalidate();
  22. }
  23. }
  24. }

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

  1. public static float applyDimension(int unit, float value,
  2. DisplayMetrics metrics)
  3. {
  4. switch (unit) {
  5. case COMPLEX_UNIT_PX:
  6. return value;
  7. case COMPLEX_UNIT_DIP:
  8. return value * metrics.density;
  9. case COMPLEX_UNIT_SP:
  10. return value * metrics.scaledDensity;
  11. case COMPLEX_UNIT_PT:
  12. return value * metrics.xdpi * (1.0f/72);
  13. case COMPLEX_UNIT_IN:
  14. return value * metrics.xdpi;
  15. case COMPLEX_UNIT_MM:
  16. return value * metrics.xdpi * (1.0f/25.4f);
  17. }
  18. return 0;
  19. }

我靠,好熟悉的代码,根据传递过来的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、完毕,经理催我做项目了

发表评论

表情:
评论列表 (有 0 条评论,654人围观)

还没有评论,来说两句吧...

相关阅读

    相关 TextView设置字体

    / 这个是用来设置字体的,比如设置显示的TextView为微软雅黑字体或者宋体、楷体等,跟大小颜色等属性无关; 将 TTF等格式的字体文件放在app-s