代码:
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
中的所有数据都会被回收。事实上,在所有的例子中,他们都建议显式地回收所有从视图的构造函数中的AttributeSet
获得的类型化数组。我认为你也应该遵循最佳实践。
TypedArray a = context.obtainStyledAttributes(attrs, set);
try {
// read attributes from a
// ...
} finally {
attributes.recycle();
}
我的猜测是,当调用onFinishInflate()
时,attrs
已经为空或不可用。
事实上,根据LayoutInflater
的代码,在布局膨胀期间传递给View构造函数的AttributeSet
实际上是基于XmlPullParser
的。onFinishInflate()
是在对其所有子视图进行充气后在父视图上调用的。
在"onFinish充气(("中,此时您似乎无法从attrs
获取属性的值。特别是如果布局中有子级,attrs
将引用同一个解析器,但解析器的位置将指向最后解析的子级的属性。