目录
Application Theme < Activity Theme
1.attr自定义属性format类型
<attr name="字符串" format="string"/>
<attr name="颜色" format="color"/>
<attr name="尺寸" format="dimension"/>
<attr name="整型" format="integer"/>
<attr name="浮点型" format="float"/>
<attr name="布尔型" format="boolean"/>
<attr name="资源引用" format="reference"/>
<attr name="百分数" format="fraction"/>
<attr name="枚举">
<enum name="name0" value="0"/>
<enum name="name1" value="1"/>
</attr>
<attr name="立死亡flag">
<flag name="name0" value="0"/>
<flag name="name1" value="1"/>
<flag name="name2" value="2"/>
</attr>
<attr name="获取多种类型 | 号隔开" format="reference|color|integer"/>
2. 声明自定义属性
<attr name="iconWidth" format="dimension"/>
<attr name="iconHeight" format="dimension"/>
attr标签属性会在R类下的attr类中生成16进制地址静态常量,比如:
public static final class attr {
public static final int iconWidth = 0x7f010000;
public static final int iconHeight = 0x7f010001;
}
代码中取属性值方法:
int[] attrKeys = {R.attr.iconWidth, R.iconHeight};
TypedArray typedArray = context.obtainStyledAttributes(set, atttrKeys);
float iconWidth = typedArray.getDimension(0, defaultValue);
float iconHeight = typedArray.getDimension(1, defaultValue);
declare-styleable标签封装attr
<declare-styleable name="MyIconView">
<attr name="iconWidth" format="dimension"/>
<attr name="iconHeight" format="dimension"/>
</declare-styleable>
使用declare-styleable封装的attr会在R类下的styleable类封装attr类下的16进制地址生成int[]数组,并生成下标索引:
public static final class styleable {
public static final int[] MyIconView = {
0x7f010000, 0x7f010001
};
public static final int MyIconView_iconWidth = 0;
public static final int MyIconView_iconHeight = 1;
}
代码中取属性值方法:
TypedArray typedArray = context.obtainStyledAttributes(set, R.styleable.MyIconView);
float iconWidth = typedArray.getDimension(R.styleable.MyIconView_iconWidth, defaultValue);
float iconHeight = typedArray.getDimension(R.styleable.MyIconView_iconHeight, defaultValue);
3. 自定义属性复用
重复的自定义属性:
<declare-styleable name="MyIconView">
<attr name="icon" format="reference"/>
<attr name="iconWidth" format="dimension"/>
<attr name="iconHeight" format="dimension"/>
</declare-styleable>
<declare-styleable name="MyImageView">
<attr name="icon" format="reference"/>
</declare-styleable>
复用自定义属性写法:
<attr name="icon" format="reference"/>
<declare-styleable name="MyIconView">
<attr name="icon"/>
<attr name="iconWidth" format="dimension"/>
<attr name="iconHeight" format="dimension"/>
</declare-styleable>
<declare-styleable name="MyImageView">
<attr name="icon"/>
</declare-styleable>
复用Android SDK已有属性:
<declare-styleable name="MyIconView">
<attr name="android:src"/>
<attr name="iconWidth" format="dimension"/>
<attr name="iconHeight" format="dimension"/>
</declare-styleable>
android:src 的 : 号是转意的语法,目的源是SDK已有属性
4. xml布局文件中使用自定义属性
系统的命名空间:xmlns:android="http://schemas.android.com/apk/res/android"
通用命名空间:
xmlns:app="http://schemas.android.com/apk/res-auto"
包名命名空间:
xmlns:app="http://schemas.android.com/apk/res/包名"
xmlns:app是自定义的属性引用名, URL:http://schemas.android.com/apk/res是默认的资源标识,实际是不可访问的
命名空间作用域:声明到根布局则全局使用,声明到单个view则只能在单个view内使用
属性使用(自定义属性使用了SDK已有属性):
<com.bin.MyIconView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
app:iconWidth="35dp"
app:iconHeight="35dp" />
5. 使用style复用xml属性
重复属性:
<com.bin.MyIconView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/ic_launcher"
app:iconWidth="35dp"
app:iconHeight="35dp" />
<com.bin.MyIconView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/ic_launcher"
app:iconWidth="35dp"
app:iconHeight="35dp" />
封装style:
<style name="MyIconView">
<item name="android:layout_width">0dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1"</item>
<item name="android:src">@drawable/ic_launcher</item>
<item name="iconWidth">35dp</item>
<item name="iconHeight">35dp</item>
</style>
注意:SDK的属性需要android:,自定义的属性直接写名字
复用属性后:
<com.bin.MyIconView
style="@style/MyIconView" />
<com.bin.MyIconView
style="@style/MyIconView" />
6. 属性优先级
View的构造方法
public View(Context context) {
this(context, null);
}
public MyCustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
this(context, attrs, defStyle, 0);
}
public MyCustomView(Context context, AttributeSet attrs, int defStyle, int defStyleRec) {
super(context, attrs, defStyle, defStyleRec);
// TODO:获取自定义属性
}
4个参数的构造方法是API21引入,若有需求请注意版本兼容,一般3个参数的构造方法可以满足需求
代码中 new ,调用第一个构造方法。
xml中调用第二个构造方法。
第三和第四个构造方法需要手动调用。
TypedArray
context中返回TypedArray的四个方法
- obtainAttributes(AttributeSet set, int[] attrs) //从layout设置的属性集中获取attrs中的属性
- obtainStyledAttributes(int[] attrs) //从系统主题中获取attrs中的属性
- obtainStyledAttributes(int resId,int[] attrs) //从资源文件定义的style中读取属性
- obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)
参数含义
AttributeSet set:从layout xml文件为view添加的属性集合。(键值)
int[] attrs:每个方法都有的参数。最终返回的TypedArray只能查找对应数组Id的属性。(键)
int defStyleAttr:从当前Activity设置的Theme中搜索的style。(键值)
int defStyleRes:备用style,当defStyleAttr为0时,并且them中未设置对应此View的defStyleAttr才生效。(键值)
int resId:直接从资源文件中定义的某个style中读取。(键值)
优先级:
1. 布局中为View显示设置的值 >
2. 布局中style指定的样式 >
3. (defStyleAttr) 布局通过主题中配置的style,代码中指定的style resId >
4. (defStyleRes) 代码中指定的style resId。当defStyleAttr为0时,并且them中未设置对应此View的defStyleAttr才生效 >
5. theme中指定的item attr属性
Application Theme < Activity Theme
注意在主题设置的属性是全局的