I столкнулся с этим вопросом сегодня. По какому-то стоит, я думаю, что есть прямолинейная работа вокруг. Вместо добавления атрибутов в тег 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
}
}
В конце концов, каждый из файлов XML, где вы хотели <include>
макет будет содержать около 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