zoukankan      html  css  js  c++  java
  • Android: TextView 及其子类通过代码和 XML 设置字体大小的存在差异的分析

    原因: 在代码中通过 setTextSize(float size) 设置,使用的是 sp 为默认单位。 而 XML 中使用了 px,所以需要使用先把做好 sp 和 px 的转换工作。

    最近在做 app 内修改字体大小,同时在设置页面有个预览界面,这个时候需要通过代码设置字体大小了

    1 tv.setTextSize(getResources().getDimension(R.dimen.XLargeTextSize));

    结果发现比通过 XML 设置的字体大小要大不少,看到了 setTextSize() 的源码,发现了问题所在。

    1. setTextSize(), 该方法调用的是 setTextSize(TypedValue.COMPLEX_UNIT_SP, size),看到了使用了一个尺寸单位 TypedValue.COMPLEX_UNIT_SP

    1     @android.view.RemotableViewMethod
    2     public void setTextSize(float size) {
    3         setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
    4     }

    跟进到 TypedValue 中,查看到常量,根据输入不同的单位,解析不同的 size,然后确定文字大小

    查看到有三个常量:(px, dip(dp), sp)

    1 /** {@link #TYPE_DIMENSION} complex unit: Value is raw pixels. */
    2     public static final int COMPLEX_UNIT_PX = 0;
    3     /** {@link #TYPE_DIMENSION} complex unit: Value is Device Independent
    4      *  Pixels. */
    5     public static final int COMPLEX_UNIT_DIP = 1;
    6     /** {@link #TYPE_DIMENSION} complex unit: Value is a scaled pixel. */
    7     public static final int COMPLEX_UNIT_SP = 2;

    2. setTextSize(int unit, float size),在这个方法中,解析了 TypedValue 中的常量,解析方法为 applyDimension()

     1     public void setTextSize(int unit, float size) {
     2         Context c = getContext();
     3         Resources r;
     4 
     5         if (c == null)
     6             r = Resources.getSystem();
     7         else
     8             r = c.getResources();
     9 
    10         setRawTextSize(TypedValue.applyDimension(
    11                 unit, size, r.getDisplayMetrics()));
    12     }

    3. TypedValue.applyDomension(),根据不同的单位,返回不同的 value。 1. 选择 px 为单位,直接返回输入的 value; 2. 选择 dp 为单位 ,返回为 value * density;3. 选择 sp 为单位,返回 value* scaledDensity

     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     }

    4. setRawTextSize(),这个方法中,调用了 mTextPaint.setTextSize(), mTextPaint 是 TextPaint 的实例, TextPaint 继承 Paint,可以看到就是调用的 Paint 的 setTextSize() 方法。

     1     private void setRawTextSize(float size) {
     2         if (size != mTextPaint.getTextSize()) {
     3             mTextPaint.setTextSize(size);
     4 
     5             if (mLayout != null) {
     6                 nullLayouts();
     7                 requestLayout();
     8                 invalidate();
     9             }
    10         }
    11     }
  • 相关阅读:
    谷歌技术"三宝"之BigTable
    谷歌技术"三宝"之谷歌文件系统
    谷歌技术"三宝"之MapReduce
    大话存储
    ASP.NET之旅--深入浅出解读IIS架构
    好网站
    ArcGIS API for Silverlight学习资料积累
    浏览器滚动条快到底部时自动加载数据
    MVC EF中Attach和Entry区别
    微信开发jssdk入门
  • 原文地址:https://www.cnblogs.com/liyiran/p/6392984.html
Copyright © 2011-2022 走看看