在自定义 View 中,大家都知道用下面的方式读取自定义属性

1
2
3
4
5
6
7
public class MyView {

public MyView(Context ctx, AttributeSet attrs) {
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.myview);
array.close();
}
}

那么我们要怎么读取 android 命名空间下的属性呢?

1
2
<LinearLayout
android:layout_width="100dp" />

很容易想到的是,既然自定义的样式在 R.styleable 这个包下面,那么系统的应该在 android.R.styleable ? 很可惜,并没有这样的资源。

方法一:

通过读取自定义属性的代码可知 R.styleable.myview 其实是一个数组

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myview">
<attr name="xx"/>
</declare-styleable>
</resources>

所以可以自己声明一个 styleable,把系统的属性组合起来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private static final int[] styleable = new int[] {
android.R.attr.layout_width, // index 0
android.R.attr.layout_height, // 1
android.R.attr.layout_margin, // 2
android.R.attr.padding // 3
};

TypedArray array = context.obtainStyledAttributes(attrs, styleable);
int n = array.getIndexCount();
for (int i = 0; i < n; i++) {
int index = array.getIndex(i);
int value = array.getDimensionPixelSize(index, 0);
}
array.close();

经我测试,这个方法 android:padding 是读取不到,所以并不推荐。

方法二:

在自定义属性中添加属性,命名成 android:xxx,与系统重名,类型不用指定。

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="myview">

<attr name="android:layout_width"/>
<attr name="android:layout_height"/>
<attr name="android:layout_margin"/>
<attr name="android:padding"/>

</declare-styleable>

</resources>
1
2
3
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.myview);
int width = array.getDimensionPixelSize(R.styleable.myview_android_layout_width, 0);
array.close();

其实这样就可以读取到对应的值,与声明系统共用一个,但是读取并不冲突,强力推荐