理解Attr,Style,Theme

概念

  • Attr:属性(Attribute),用于指定UI的某种风格样式,比如android:layout_width就是一种Attr;
  • Style:风格,一系列Attr的集合,用于为UI指定一个“复合风格样式”;
  • Theme:主题,与Style的作用一样,区别于Style的作用范围是View,而Theme的作用范围是Activity或Application

Attr

只有在自定义View的时候会用到Attr

    
            
               
                
            
        

            
                
               
            
    


layout_xxx属性的取值范围为三个枚举值 fill_parent,wrap_content 或是具体大小dp

Attr的类型,可取的值有以下类型:

  • color:颜色值,如#000000
  • reference:引用某一资源ID。如@drawable/xxx
  • boolean:布尔值,true或false
  • dimension:尺寸值,可以为wrap_content、match_parent或是具体大小(xx dp)
  • float:浮点型
  • fraction:百分数
  • integer:整型
  • string:字符串类型
  • enum:枚举类型,各个取值互斥
  • flag:标记位,各个取值可用“|”连接

获取自定义Attr

public MyView(Context context, AttributeSet attrs) {
  super(context, attrs);
  TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyStyle);
  String name = ta.getString(R.styleable.MyStyle_myName, "absfree");
   . . .
 ta.recycle()
}

而上面代码中的obtainStyledAttributes方法最终调用的是以下重载版本的方法

public final TypedArray obtainStyledAttributes (
           AttributeSet set                    //属性集
         , int[] attrs                              //想要获取的属性
         , int defStyleAttr                    //表示一个指向Style的类型为reference的Attr
        , int defStyleRes)                   //表示Style的资源ID
后两个参数都用于指定默认Style,当从attrs中找不到我们想要获取的属性时,就会使用默认Style,其中defStyleAttr的优先级高于defStyleRes

自定义Style

在res/values/styles.xml的标签内增加如下内容


在MyView类中,我们便可以通过Theme的obtainStyledAttributes获取到自定义Style的值。比如以下代码可以后去到MyStyle中的myName的值。

final Resources.Theme theme = context.getTheme();
TypedArray ta = theme.obtainStyledAttributes(attrs, R.styleable.MyStyle, 
    defStyleAttr, defStyleRes);
String name = ta.getString(R.styleable.MyStyle_myName);
ta.recycle();

使用Theme

自定义Theme的方法与自定义Style相同,也使用

  1. 建立attr.xml文件 里面放自定义View需要的属性,这个时候可以如下引用attr属性,其他地方也可以这样使用

        ?attr/config_color_pressed
    

这样来达到app样式统一。获取attr属性的时候 可以通过下面的方法

public static float getAttrFloatValue(Context context, int attrRes){
        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(attrRes, typedValue, true);
        return typedValue.getFloat();
    }

    public static int getAttrColor(Context context, int attrRes){
        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(attrRes, typedValue, true);
        return typedValue.data;
    }

    public static ColorStateList getAttrColorStateList(Context context, int attrRes){
        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(attrRes, typedValue, true);
        return ContextCompat.getColorStateList(context, typedValue.resourceId);
    }

    public static Drawable getAttrDrawable(Context context, int attrRes){
        int[] attrs = new int[] { attrRes };
        TypedArray ta = context.obtainStyledAttributes(attrs);
        Drawable drawable = ta.getDrawable(0);
        ta.recycle();
        return drawable;
    }

    public static int getAttrDimen(Context context, int attrRes){
        TypedValue typedValue = new TypedValue();
        context.getTheme().resolveAttribute(attrRes, typedValue, true);
        return TypedValue.complexToDimensionPixelSize(typedValue.data, QMUIDisplayHelper.getDisplayMetrics(context));
    }

具体可以参考腾讯QMUI安卓版本的代码

你可能感兴趣的:(理解Attr,Style,Theme)