自定义控件-3.加强用法,多重参数类型

来源:互联网 发布:macbook平面设计软件 编辑:程序博客网 时间:2024/06/11 18:55
 使用系统控件时,如layout_height/width参数这种,都是有两种值的
一种是枚举型wrap_content和match_parent/fill_parent,另一种则是具体的值200dp这样的
则自定义参数的申明则需要将两者结合起来

比如我们可以在自定义控件的宽高控制里加这么一个参数,equal_textsize,使用时保证drawable图片大小和文字一样
具体如下,在以前基础上添加enum子项,支持枚举值,value为了保证不和dimension冲突取负数~
自定义图片宽高属性中都可以添加一个enum

<attr name= "drawableWidth" format ="dimension">
    <enum name ="equal_textsize" value="-2" />
</attr>

对应类代码如下

public class DrawableTextView extends TextView {

      private static final int WRAP_DRAWABLE = -1;
      private static final int EQUAL_TEXTSIZE = -2;

      public DrawableTextView(Context context) {
             this(context, null);
      }

      public DrawableTextView(Context context, AttributeSet attrs) {
             this(context, attrs, 0);
      }

      public DrawableTextView(Context context, AttributeSet attrs, int defStyle) {
             super(context, attrs, defStyle);

             // 绑定attrs 属性
            TypedArray ta = context.obtainStyledAttributes(attrs,
                        R.styleable. DrawableTextView);
             // 获取自定义参数在使用时赋的具体值,由于值可能有两种不同的类型,所以自定义了一个方法
             int widthPx = getIntOrDimen(ta,
                        R.styleable. DrawableTextView_drawableWidth, WRAP_DRAWABLE);
             int heightPx = getIntOrDimen(ta,
                        R.styleable. DrawableTextView_drawableHeight, WRAP_DRAWABLE);

             // 获取textview 的图片集合,上左下右方向共4个
            Drawable[] drawables = getCompoundDrawables();
            Drawable drawable = null;
             for ( int i = 0; i < drawables. length; i++) {
                   if (drawables[i] != null) {
                         // 获取到某方向有图片的 drawable
                        drawable = drawables[i];
                         break;
                  }
            }

             // textsize用的是 sp作为size,而我们希望图片高度和文字部分一样,图片用的是 dp作为单位,
             // 两者转为px的比例有时候是不同的(大部分情况下是一样的)
             // 比如我用的平板, sp对应的scaledDensity为1.15, 而 dp对应的density为1.0,所以需要转换一下
            Context c = getContext();
            Resources r = c == null ? Resources. getSystem() : c.getResources();
            DisplayMetrics metrics = r.getDisplayMetrics();
             float scale = metrics. scaledDensity / metrics. density;
             float tvSize = getTextSize();
             // 如果是特殊枚举值EQUAL_TEXTSIZE,则计算 textsize对应的所需像素值
             if (widthPx == EQUAL_TEXTSIZE) {
                  widthPx = ( int) (tvSize / scale + 0.5f);
            }
             // 如果是特殊枚举值EQUAL_TEXTSIZE,则计算 textsize对应的所需像素值
             if (heightPx == EQUAL_TEXTSIZE) {
                  heightPx = ( int) (tvSize / scale + 0.5f);
            }
             // 根据获取到的宽高设置图片,达到对 drawable大小的控制
             if (widthPx > 0 && heightPx > 0) {
                  drawable.setBounds(0, 0, widthPx, heightPx);
            }
             // 将改好的图片设置回去
            setCompoundDrawables(drawables[0], drawables[1], drawables[2],
                        drawables[3]);

            ta.recycle();
      }

      private int getIntOrDimen(TypedArray a, int index, int defValue) {
             // 获取所需参数的类型值对象
            TypedValue tv = a.peekValue(index);
             int v = defValue;
             if (tv != null) {
                   // 判断是否为dimension类型
                   boolean isDimen = tv. type == TypedValue.TYPE_DIMENSION;
                   // 如果是则获取dimension值,如果不是,则获取枚举项value对应的 int
                   // 比如我们的例子里就是equal_textsize对应的整数-2
                  v = isDimen ? a.getDimensionPixelSize(index, defValue)
                              : a.getInt(index, defValue);
            }
             return v;
      }
}

核心代码为getIntOrDimen,通过peekValue方法判断控件参数值类型,然后再利用对应方法获取到值,
统一转为int型返回,判断如果是特殊的-2则进行相关处理


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 色弱高考体检时没查出来怎么办 公司福利体检查二对半怎么办 高考体检表复印件丢了怎么办 高考体检表身高填错了怎么办 大学档案高考体检表丢了怎么办 工厂组织体检我有乙肝怎么办 我有乙肝单位组织体检怎么办? 矮腰袜子老掉怎么办 短腰袜子老下滑怎么办 中考体检结果丢了怎么办 咳嗽左胸围一处刺痛怎么办? 阴茎小父母催婚怎么办 头发扎进指甲缝怎么办 指甲缝扎流血了怎么办 中考考差了高中怎么办 骨折后我抽烟了怎么办 五年级科学考不好怎么办 考试连续考差了怎么办 客户说没考虑好怎么办 小孩生殖器痒经常用手抓怎么办 孩子在幼儿园生殖器官受伤怎么办? 被骗了3000块钱怎么办 小说 月经来了想体检怎么办 尿检的时候遇上月经期怎么办 消防兵改革那新兵怎么办 教师资格证体检有问题怎么办 检兵合格还在上学怎么办 运动后肌肉肿了怎么办 打架用力过猛肌肉疼痛怎么办 军检只要一项不合格怎么办 体检身高差一厘米怎么办 体检身高差两公分怎么办 体检身高差10厘米怎么办 孩子的爸爸总是打游戏怎么办 拉屎屁眼疼还有血怎么办 家里冼澡要等好多冷水怎么办 孕晚期小孩头大怎么办 报考警校体检不合格退回怎么办? 入职体检视力0.1怎么办 屁扒骨折疼要怎么办 宝宝发高烧怎么办能快速退烧