美文网首页week.io
Android 自定义控件中单位转换

Android 自定义控件中单位转换

作者: HelloVass | 来源:发表于2015-11-30 11:58 被阅读302次

    在我们编写自定义控件的时候常常会需要进行单位转换,这个时候,这个再熟悉不过的工具类—— DisplayUtil 就会出现在我们的自定义控件中。

     private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DotViewLayout);
        // 默认 indicator 间距 10dp
        mIndicatorSpace = typedArray.getInt(R.styleable.DotViewLayout_indicator_space,
            DisplayUtil.dip2px(context, 10));
    

    DisplayUtil 源码

    public class DisplayUtil {
    
        public static int px2dip(Context context, float px) {
            float scale = context.getResources().getDisplayMetrics().density;
            return (int) (px / scale + 0.5f);
        }
    
        public static int dip2px(Context context, float dp) {
            float scale = context.getResources().getDisplayMetrics().density;
            return (int) (dp * scale + 0.5f);
        }
    }
    

    但是,有时候又懒得 copy 这个工具类。后来发现,Android Framework 是提供了相应的工具类供我们使用的。

    TypedValue 中的 applyDimension() 方法:

        /**
         * 
         * @param unit The unit to convert from.
         * @param value The value to apply the unit to.
         * @param metrics Current display metrics to use in the conversion -- 
         *                supplies display density and scaling information.
         */
        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;
        }
    

    该方法将传入的 value 值转变为标准尺寸,那么我们的自定义控件就可以不用依赖 DisplayUtil

    之前的栗子就可以这么写:

    mIndicatorSpace = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10,getResources().getDisplayMetrics());
    
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DotViewLayout);
    // 默认 indicator 间距 10dp
    mIndicatorSpace = typedArray.getInt(R.styleable.DotViewLayout_indicator_space,mIndicatorSpace);
    

    笔者认为:虽然自定义控件了多了好多代码,但是,减少了对 DisplayUtil 的依赖(哈哈,不用粘贴 DisplayUtil 了),我们的自定义控件发布时也变得 clean 多了!

    相关文章

      网友评论

      • Schnee:我很好奇你是怎么发现framework里面有这个功能
        Schnee:@HelloVass :v:
        HelloVass:@Schnee 看一些有名的开源控件啊,他们的源码里就没有 displayutil 这个类,后来发现他们都是用 framework 里的,哈哈
        HelloVass:@Schnee 看一些有名的开源控件啊,他们的源码里就没有 displayutil 这个类,后来发现他们都是用 framework 里的,哈哈

      本文标题:Android 自定义控件中单位转换

      本文链接:https://www.haomeiwen.com/subject/ioljhttx.html