I se encontró con este problema hoy. Por lo que sea que valga, creo que hay una solución directa. En lugar de agregar atributos a la etiqueta de inclusión, cree una vista de contenedor personalizada para incluir y agregar atributos a esa. Luego, haz la inclusión desde el contenedor. Haga que la implementación de la clase contenedora extraiga los atributos y los transfiera a su único elemento secundario, que es la vista raíz del diseño de inclusión.
Por lo tanto, decimos que declaramos algunos atributos personalizados para un envoltorio llamada SingleSettingWrapper como esto -
<declare-styleable name="SingleSettingWrapper">
<attr name="labelText" format="string"/>
</declare-styleable>
Entonces, creamos dos clases de vista personalizada - una para la envoltura (SingleSettingWrapper) y uno para el niño (SingleSettingChild) que se incluirá -
<!-- 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>
Para el niño, podemos poner cualquier distribución compleja que queramos. Voy a poner algo básico, pero en realidad se puede incluir cualquier cosa -
<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>
Para la envoltura (esta es la clave), leemos todos nuestros atributos personalizados en el constructor. Luego, anulamos ViewAdded() y pasamos esos atributos personalizados a nuestro hijo.
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);
*/
}
}
Opcionalmente, se puede aplicar también al niño y tienen que recibir los mensajes de la envoltura y modificar en sí (en lugar de tener la envoltura modificar el niño como lo hice anteriormente).
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
}
}
Al final del día, cada uno de los archivos XML donde quería <include>
su diseño contendrá aproximadamente 7 líneas de XML para la envoltura + incluir en lugar de la única incluyen que quería, pero si el la vista incluida contiene cientos de líneas, aún estás mucho mejor. Por ejemplo:
<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>
En la práctica, esto parece funcionar bastante bien y es relativamente fácil de configurar. Espero que esto ayude a alguien.
[El enlace de datos no lo hace soporte incluido como hijo directo de un elemento de fusión.] (https://developer.android.com/topic/libraries/data-binding/index.html) – samosaris