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?

Kamil Nekanowicz
fuente

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"/>
....
George Mount
fuente
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

Khemraj
fuente
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)
Cosmin Constantin Firta
fuente
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}" />
Rodrigo Salomao
fuente
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");
Sadeq Hitex
fuente