Magic with obtainStyledAttributes方法

时间:2014-07-09 10:11:57

标签: android

代码:

public class CustomLayoutWithText extends LinearLayout {

    private Context context;
    private AttributeSet attrs;

    public CustomLayoutWithText(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this.attrs = attrs;
        fooAttrs();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        fooAttrs();
    }

    private void fooAttrs() {
        int[] set = {
            android.R.attr.text        // idx 0
        };
        TypedArray a = context.obtainStyledAttributes(attrs, set);
        Log.d(null, a.getString(0));
    }
}

和XML:

<com.korovyansk.android.views.CustomLayoutWithText
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="Some text"/>

合理预期输出将是:
    一些文字
    一些文字

但是:
    一些文字
    空

为什么第二次出现空?以及如何避免它?

1 个答案:

答案 0 :(得分:1)

我认为attrs中的所有数据都会被回收。事实上,在各地的示例中,他们建议从View的构造函数中的AttributeSet显式回收所有获得的类型化数组。我认为你也应该遵循最佳实践。

    TypedArray a = context.obtainStyledAttributes(attrs, set);
    try {
        // read attributes from a
        // ...
    } finally {
        attributes.recycle();
    }

我的猜测是,当调用onFinishInflate()时,attrs已空或无法使用。

实际上,根据LayoutInflater的代码,在布局膨胀期间传递给View构造函数的AttributeSet实际上基于XmlPullParser。在给所有孩子充气后,在父视图上调用onFinishInflate()

现在看起来就像在onFinishInflate()&#39;您无法从attrs获取属性的值。特别是如果您的布局中有子项 - attrs将引用相同的解析器,但解析器的位置将指向最后解析的子项的属性。