【问题标题】:Magic with obtainStyledAttributes method使用 gainStyledAttributes 方法的魔法
【发布时间】:2014-07-09 10:11:56
【问题描述】:

代码:

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"/>

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

但它是:
一些文字

为什么第二次显示为空?又该如何避免呢?

【问题讨论】:

  • 转储 attrs 并查看它们是否改变
  • @pskink attrs 是一个巨大的对象,hashCode 返回相同的值,但它可能没有被覆盖。转储、toString 或其他什么方法?
  • 使用 getAttributeName/getAttributeValue ?

标签: android


【解决方案1】:

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

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

我的猜测是,当onFinishInflate() 被调用时,attrs 已经为空或不可用。

其实根据LayoutInflater的代码,布局膨胀时传入View构造函数的AttributeSet其实是基于XmlPullParseronFinishInflate() 在膨胀所有子视图后在父视图上调用。

看起来此时在“onFinishInflate()”中,您无法从attrs 获取属性值。特别是如果您的布局中有子元素 - attrs 将引用同一个解析器,但解析器的位置将指向最后一个解析的子元素的属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-14
    • 2019-06-06
    • 2015-08-08
    • 2016-04-09
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    相关资源
    最近更新 更多