我今天遇到这个问题。无论它是值得的,我认为这是一种直接的工作。不要为include标签添加属性,而是为include添加属性并为其添加属性。然后,从包装器中进行包含。让包装类实现提取属性并传递给它的单个子对象,这是包含布局的根视图。
所以,说我们宣布了一个名为SingleSettingWrapper像这样的包装一些自定义的属性 -
<declare-styleable name="SingleSettingWrapper">
<attr name="labelText" format="string"/>
</declare-styleable>
然后,我们创建了两个自定义视图类 - 一个用于包装(SingleSettingWrapper)和一个孩子(SingleSettingChild )将包括 -
<!-- You will never end up including this wrapper - it will be pasted where ever you wanted to include. But since the bulk of the XML is in the child, that's ok -->
<com.something.SingleSettingWrapper
android:id="@+id/wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:labelText="@string/my_label_string">
<!-- Include the child layout -->
<include layout="@layout/setting_single_item"/>
</com.something.SingleSettingWrapper>
对于孩子,我们可以把任何复杂的布局,在那里,我们想要的。我只是把一些基本的东西,但实际上可以包括任何 -
<com.something.SingleSettingItem
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout >
<!-- add whatever custom stuff here -->
<!-- in this example there would be a text view for the label and maybe a bunch of other stuff -->
<!-- blah blah blah -->
</RelativeLayout>
</com.something.SingleSettingItem>
对于包装(这是关键),我们看到在构造函数中我们所有的自定义属性。然后,我们重写onViewAdded()并将这些自定义属性传递给我们的孩子。
public class SingleSettingWrapper extends FrameLayout
{
private String mLabel;
public SingleSettingWrapper(Context context, AttributeSet attrs)
{
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.SingleSettingWrapper,
0, 0);
mLabel = a.getString(R.styleable.SingleSettingWrapper_labelText);
a.recycle();
}
public void onViewAdded(View child)
{
super.onViewAdded(child);
if (!(child instanceof SingleSettingItem))
return;
((TextView)child.findViewById(R.id.setting_single_label)).setText(mLabel);
/*
Or, alternatively, call a custom method on the child implementation -
((SingleSettingItem)child)setLabel(mLabel);
*/
}
}
可选,可以实现孩子太并将其从包装接收消息和修改本身(而不是有包装修改的孩子就像我上面一样)。
public class SingleSettingItem extends LinearLayout
{
public SingleSettingItem(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public void setLabel(String l)
{
// set the string into the resource here if desired, for example
}
}
在这一天结束时,每个地方你想<include>
的XML文件的布局将包含约7 XML的线包装+包括的,而不是单一的包括你想要的,但如果包含视图包含数百行你仍然更好。例如 -
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- this is the beginning of your custom attribute include -->
<com.something.SingleSettingWrapper
android:id="@+id/my_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
custom:labelText="@string/auto_lock_heading">
<include layout="@layout/setting_single_item"/>
</com.something.SingleSettingWrapper>
<!-- this is the end of your custom attribute include -->
</LinearLayout>
实际上,这似乎工作得很好,而且设置起来相对简单。我希望它能帮助别人。
[数据绑定不支持包括作为一个合并元素的直接孩子。](https://developer.android.com/topic/libraries/data-binding/index.html) – samosaris