自定义View笔记(二) ---深入理解自定义属性

注:该笔记是整理学习鸿洋大神自定义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 */
<declare-styleable name="test">
    <attr name="android:text" />
    <attr name="testAttr" format="integer" />
</declare-styleable>

在类中这么获取:ta.getString(R.styleable.test_android_text);布局文件中直接android:text=”@string/hello_world”即可。

三、能不能在 view 属性定义时,不使用 declare-styleable 标签
解答:
可以不使用,但是当在类中获取属性值时,需要在声明一个 int 数组,用于存储 attr 的 id,并且我们根据元素的在数组中的位置,定义了一些整形的常量代表其下标,然后通过TypedArray进行获取。所以建议使用
例如:
attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<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();
    }
}

猜你喜欢

转载自blog.csdn.net/Android_Programmer/article/details/78295441