1.组件的属性
自定义的组件继承自View后就会具备若干的默认属性。
除了View 的默认属性之外、我们也可以为组件自定义属性,自定义属性应遵循以下步骤:
1)在 res/values/attrs.xml 文件中为指定组件定义 declare-styleable 标记, 并将所有的属性
都定义在该标记中;(若没有,自行创建)
2)在 layout 文件中使用自定义属性;
3)在组件类的构造方法中读取属性值。example:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CirclePhotoView"> <attr name="text" format="string" /> </declare-styleable> </resources>
一般来讲,定义好属性的名称和类型之后,属性就可以使用了,但是在布局文件中,要注意属性的命名空间(namespace),默认的命名空间是“Android”,是由语句
xmlns:android="http://schemas.android.com/apk/res/android"
所决定的,但是对于自定义属性,必须定义其他的命名空间,
xmlns:app="http://schemas.android.com/apk/res-auto"
其中,“app”是可以使用其他的进行替代,但是后面"http://schemas.android.com/apk/res-auto"则是固定的,当有了这个命名空间之后,之前的自定义属性便可以对其进行使用了。当组件运行之后,所有的属性都将保存在AttributeSet集合中并通过构造方法进行传入,我们可以通过TypedArray读取指定的属性值。
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CirclePhotoView);
text = typedArray.getString(R.styleable.CirclePhotoView_text);
typedArray.recycle();
2.读取来自style和theme中的属性
关于组件的属性,可以在四个地方进行定义:
1)组件中定义
2) 组件的style属性中进行定义
3)theme中进行定义
4)theme的style的属性中进行定义
关于四个地方获取属性的方法,首先我们在attr.xml中定义如下四个属性:
<resources>
<declare-styleable name="CirclePhotoView">
<attr name="attr1" format="string" />
<attr name="attr2" format="string" />
<attr name="attr3" format="string" />
<attr name="attr4" format="string" />
</declare-styleable>
<attr name="myStyle" format="reference" />
</resources>
其中,“myStyle”类型为reference,用于theme的style属性。
下面四个属性将应用于不同的场合,在布局文件中:
<com.example.hu.customizationview.CirclePhotoView
android:id="@+id/myview"
style="@style/viewStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
app:attr1="你好啊 你是谁啊" />
在res/values/styles.xml中:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="attr3">3你说啥 我不知道</item>
<item name="myStyle">@style/myDefaultStyle</item>
</style>
<style name="myDefaultStyle">
<item name="attr4">这个是4</item>
</style>
<style name="viewStyle">
<item name="attr2">你真的不知道这个是2?</item>
</style>
</resources>
最后在CirclePhotoView对属性值进行获取:
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CirclePhotoView,
defStyleAttr, R.style.myDefaultStyle);
String attr1 = a.getString(R.styleable.CirclePhotoView_attr1);
String attr2 = a.getString(R.styleable.CirclePhotoView_attr2);
String attr3 = a.getString(R.styleable.CirclePhotoView_attr3);
String attr4 = a.getString(R.styleable.CirclePhotoView_attr4);
在上面的构造方法中,我们调用了
public TypedArray obtainStyledAttributes (AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes)。在该方法中:
1)set:属性值的集合。
2)attrs:我们要获取的属性的资源 ID 的一个数组, 我们定义了 attr1、 attr2、 attr3 和 attr4, 这
4 个属性自动生成的索引会存储到 R.styleable.AttrView 数组中, 该数组就是 attrs 参数。
3)defStyleAttr:当前 Theme 中 style 属性, 如果组件和组件的 style 属性都没有为 View 指定属
性时,将从 Theme 的 Style 中查找相应的属性值。
4)defStyleRes:指向一个 Style 的资源 ID,但是仅在 defStyleAttr 为 0 或 defStyleAttr 不为 0 但
Theme 中没有为 defStyleAttr 属性赋值时起作用。
在下面的图中展示了attr属性的读取顺序: