注:该笔记是整理学习鸿洋大神自定义View系列博客的部分知识点。
一、TypedArray 与 AttributeSet 获取 View 属性的区别
AttributeSet获取方式:
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
int count = attrs.getAttributeCount();
for (int i = 0; i < count; i++) {
String attrName = attrs.getAttributeName(i);
String attrVal = attrs.getAttributeValue(i);
Log.e(TAG, "attrName = " + attrName + " , attrVal = " + attrVal);
}
}
TypedArray获取方式:
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.test);
String text = ta.getString(R.styleable.test_testAttr);
int textAttr = ta.getInteger(R.styleable.test_text, -1);
Log.e(TAG, "text = " + text + " , textAttr = " + textAttr);
ta.recycle();
}
当布局文件这样设置属性时:
<com.example.test.MyTextView
android:layout_width="@dimen/dp100"
android:layout_height="@dimen/dp200"
zhy:testAttr="520"
zhy:text="@string/hello_world" />
输出的结果为:
MyTextView(4692): attrName = layout_width , attrVal = @2131165234
MyTextView(4692): attrName = layout_height , attrVal = @2131165235
***MyTextView(4692): attrName = text , attrVal = @2131361809***
MyTextView(4692): attrName = testAttr , attrVal = 520
>>use typedarray
***MyTextView(4692): text = Hello world! , textAttr = 520***
结论:TypedArray其实是用来简化我们的工作的,比如上例,如果布局中的属性的值是引用类型(比如:@dimen/dp100),如果使用 AttributeSet 去获得最终的像素值,那么需要第一步拿到 id,第二步再去解析id。而 TypedArray 正是帮我们简化了这个过程。
二、如果系统中已有明确的属性,能不能在 view 属性定义时直接使用
解答:
可以直接使用,使用方式:
/** 注意声明和使用的区别,差别就是有没有format */
"test">
"android:text" />
"testAttr" format="integer" />
在类中这么获取:ta.getString(R.styleable.test_android_text);布局文件中直接android:text=”@string/hello_world”即可。
三、能不能在 view 属性定义时,不使用 declare-styleable 标签
解答:
可以不使用,但是当在类中获取属性值时,需要在声明一个 int 数组,用于存储 attr 的 id,并且我们根据元素的在数组中的位置,定义了一些整形的常量代表其下标,然后通过TypedArray进行获取。所以建议使用。
例如:
attrs.xml
<resources>
<attr name="testAttr" format="integer" />
resources>
MyTextView类
public class MyTextView extends View {
private static final int[] mAttr = { android.R.attr.text, R.attr.testAttr };
private static final int ATTR_ANDROID_TEXT = 0;
private static final int ATTR_TESTATTR = 1;
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, mAttr);
String text = ta.getString(ATTR_ANDROID_TEXT);
int textAttr = ta.getInteger(ATTR_TESTATTR, -1);
Log.e(TAG, "text = " + text + " , textAttr = " + textAttr);
ta.recycle();
}
}