在我们编写自定义控件的时候常常会需要进行单位转换,这个时候,这个再熟悉不过的工具类—— 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 多了!
网友评论