2010-04-13 14 views
81

No puedo sobrescribir los atributos al usar <incluir> en mis archivos de diseño de Android. Cuando buscaba insectos, encontré disminuido Issue 2863:¿La etiqueta "incluir" de Android XML Layout realmente funciona?

"incluyen la etiqueta se rompe (anulando parametros de diseño nunca funciona)"

Desde Romain indica que esto funciona en los bancos de pruebas y sus ejemplos, debo estar haciendo algo incorrecto.

Mi proyecto se organiza así:

res/layout 
    buttons.xml 

res/layout-land 
    receipt.xml 

res/layout-port 
    receipt.xml 

El buttons.xml contiene algo como esto:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <Button .../> 

    <Button .../> 
</LinearLayout> 

Y los archivos receipt.xml vertical y horizontal ser algo como:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical"> 

    ... 

    <!-- Overridden attributes never work. Nor do attributes like 
     the red background, which is specified here. --> 
    <include 
     android:id="@+id/buttons_override" 
     android:background="#ff0000" 
     android:layout_width="fill_parent" 
     layout="@layout/buttons"/> 

</LinearLayout> 

¿Qué me estoy perdiendo?

Respuesta

129

Acabo de encontrar el problema. En primer lugar, solo puede reemplazar los atributos de layout_ *, por lo que el fondo no funcionará. Ese es un comportamiento documentado y simplemente un descuido de mi parte.

El verdadero problema se encuentra en LayoutInflater.java:

// We try to load the layout params set in the <include /> tag. If 
// they don't exist, we will rely on the layout params set in the 
// included XML file. 
// During a layoutparams generation, a runtime exception is thrown 
// if either layout_width or layout_height is missing. We catch 
// this exception and set localParams accordingly: true means we 
// successfully loaded layout params from the <include /> tag, 
// false means we need to rely on the included layout params. 
ViewGroup.LayoutParams params = null; 
try { 
    params = group.generateLayoutParams(attrs); 
} catch (RuntimeException e) { 
    params = group.generateLayoutParams(childAttrs); 
} finally { 
    if (params != null) { 
    view.setLayoutParams(params); 
    } 
} 

Si el <incluyen> etiqueta no incluye tanto layout_width y layout_height, la RuntimeException se produce y se maneja en silencio, sin ninguna declaración de registro, incluso .

La solución es incluir siempre tanto layout_width como layout_height cuando se usa la etiqueta <include>, si desea sobrescribir alguno de los atributos layout_ *.

Mi ejemplo debe cambiar a:

<include 
     android:id="@+id/buttons_override" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     layout="@layout/buttons"/> 
+33

Esto es ridículo. Nunca he sido capaz de hacer que esto funcione, e incluso vi mencionar la documentación que necesitaba tanto la altura como el ancho si intentaba anular las dimensiones, que supuse que eran de alto y ancho. Sin embargo, todo lo que intentaba anular es el margen, que en realidad no es una dimensión. ¿Por qué diablos necesito especificar ambos o incluso cualquiera de esos cuando todo lo que quiero cambiar es el layout_marginRight? Grrr, Android, a veces me frustras demasiado. –

+2

Eric, debes aceptar tu propia respuesta como la solución. –

+0

FYI Android Lint le dará un error (El parámetro de diseño layout_height se ignora a menos que layout_width también se especifique en tag) si no anula los atributos de alto y ancho – binary

2

he encontrado a veces extraño incluyendo el androide: Etiqueta de Identificación cuando se utiliza el constructor de interfaz gráfica de usuario en Eclipse. Asegurándome (cuando lo noté) de que agregué a un TextView del constructor, el ID que estoy usando en el diseño de ListView.

<TextView android:text="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
... 

convierte

<TextView android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
... 

En vez de conseguir 'falsa' 'falsa' me sale :) e incluye el trabajo bien.

10

presenté una enhancement request para permitir todo incluido atributos para ser anulado:

Supongamos que tengo dos diseños idénticos distintos de los valores de un campo TextView. En este momento, modifico el diseño en el tiempo de ejecución o duplico el XML.

Por ejemplo, para pasar dos parámetros con valores "Hola" y "mundo" a Layout1:

<include layout="@layout/layout1a" params="textView=hello|editText=world" />

layout1a.xml:

<merge><TextView text="@param/textView"><EditText hint="@param/editText"></merge>

una implementación alternativa haría romper la encapsulación y permitiría la instrucción include para anular valores como:

<include layout="@layout/layout1b" overrides="@id/textView.text=hello|@id/editText.hint=world" />

layout1b.xml:

<merge><TextView id="@+id/textView"><EditText hint="@+id/editText"></merge>

+1

no estoy seguro de por qué tiene 2 votos negativos –

+0

Teniendo en cuenta el nuevo enlace de datos cosas, el '' se usa aún más a menudo ahora, el reemplazo de atributos es una función realmente imprescindible –

Cuestiones relacionadas