Enlace de datos de Android mediante la etiqueta de inclusión


116

Nota de actualización:

El ejemplo anterior funciona correctamente , porque la versión 1.0-rc4 solucionó el problema de necesitar la variable innecesaria.

Pregunta original:

Hago exactamente como se describe en la documentación y no funciona:

main.xml:

<layout xmlns:andr...
    <data>
    </data>
       <include layout="@layout/buttons"></include>
....

botones.xml:

<layout xmlns:andr...>
    <data>
    </data>
    <Button
        android:id="@+id/button"
        ...." />

MyActivity.java:

 ... binding = DataBindingUtil.inflate...
binding.button; ->cannot resolve symbol 'button'

como conseguir el boton?

Respuestas:


206

El problema es que el diseño incluido no se considera un diseño enlazado a datos. Para que actúe como uno, debe pasar una variable:

botones.xml:

<layout xmlns:andr...>
  <data>
    <variable name="foo" type="int"/>
  </data>
  <Button
    android:id="@+id/button"
    ...." />

main.xml:

<layout xmlns:andr...
...
   <include layout="@layout/buttons"
            android:id="@+id/buttons"
            app:foo="@{1}"/>
....

Luego, puede acceder a los botones indirectamente a través del campo de botones:

MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.button

A partir de 1.0-rc4 (recién lanzado), ya no necesita la variable. Puede simplificarlo para:

botones.xml:

<layout xmlns:andr...>
  <Button
    android:id="@+id/button"
    ...." />

main.xml:

<layout xmlns:andr...
...
   <include layout="@layout/buttons"
            android:id="@+id/buttons"/>
....

6
1.0-rc4 ahora soluciona el problema de necesitar la variable innecesaria. Ahora puede utilizar simplemente: <include layout="@layout/buttons" android:id="@+id/buttons"/>. Aún necesita la identificación para que produzca un campo público para que pueda acceder a la Vista de botones.
George Mount

1
¿Alguien más tiene problemas para vincular eventos de clic en el diseño?
Nilzor

5
Enlace de datos con soporte de inclusión. developer.android.com/topic/libraries/data-binding/…
sowmia

1
El punto principal para recordar aquí es obtener la referencia del botón, debe hacer en binding.{id of include tag}.buttonlugar de binding.button. Me tomó un tiempo resolverlo.
Rishabh876

1
@NeonWarge Hay un ejemplo completo en developer.android.com/topic/libraries/data-binding/… . Agrega "El enlace de datos no admite la inclusión como elemento secundario directo de un elemento de combinación"
Ewan

38

Ejemplo fácil y completo

Simplemente configure el iddiseño incluido y úselo binding.includedLayout.anyView.

Este ejemplo ayuda a pasar un valor <includey acceder a las vistas incluidas en el código.

Paso 1

Tienes layout_common.xml , quieres pasar Stringal diseño incluido.

Va a crear Stringvariable en el diseño y se refieren este Stringa TextView.

<data>
    // declare fields
    <variable
        name="passedText"
        type="String"/>
</data>

<TextView
    android:id="@+id/textView"
    ...
    android:text="@{passedText}"/> //set field to your view.

Paso 2

Incluya este diseño en el diseño principal. Dar un iddiseño incluido para que podamos usarlo en la clase de enlace. Ahora puede pasar String passedTexta su <includeetiqueta.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <LinearLayout
        ..
        >

        <include
            android:id="@+id/includedLayout"
            layout="@layout/layout_common"
            app:passedText="@{@string/app_name}" // here we pass any String 
            />

    </LinearLayout>
</layout>
  • Puedes usar ahora binding.includedLayout.textView en tu clase.
  • Puede pasar cualquier variable al diseño incluido como el anterior.

    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.includedLayout.textView.setText("text");

Nota Ambos diseños (padre e incluido) deben estar binding layoutenvueltos con<layout


En su respuesta, manejó el evento setText programáticamente, en lugar de TextView si hubiera sido un botón, entonces, ¿cómo habría manejado su evento de clic? Sé que programáticamente binding.includedLayout.button.setOnClickListenersería la alternativa, pero ¿qué pasa si quiero usar el onClickatributo en XML? sí mismo ?
iCantC

Puede pasar OnClickListeneral diseño incluido. incluso puedes pasar cualquier cosa en la encuadernación. Marque esta respuesta, si necesita más ayuda, hágamelo saber. stackoverflow.com/a/51722829/6891563
Khemraj

1
Cuando hago esto, obtengo un campo en blanco para passedText. La única diferencia es que no incluyo el código MainActivity porque solo quiero pasar el recurso de cadena en <include> y dejarlo así. ¿Por qué siempre está en blanco?
Elliptica

3

Otra cosa interesante sobre esto es que puede pasar variables al diseño importado desde el cuaderno de esta manera:

MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.setVariable(BR.varID, variable)

3

Puede hacer que su enlace funcione en su inclusión simplemente agregando una ID así:

<include
            android:id="@+id/loading"
            layout="@layout/loading_layout"
            bind:booleanVisibility="@{viewModel.showLoading}" />

2

solo establece una identificación para tu diseño de inclusión

    <include
        android:id="@+id/layout"
        layout="@layout/buttons" />

luego

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING es res / layout / buttons.xml

ahora :

binding.button.setText("simple_Way");
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.