Associazione dati Android utilizzando il tag include


116

Nota di aggiornamento:

L'esempio sopra funziona correttamente , perché la versione 1.0-rc4 ha risolto il problema della necessità della variabile non necessaria.

Domanda originale:

Faccio esattamente come è descritto nella documentazione e non funziona:

main.xml:

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

buttons.xml:

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

MyActivity.java:

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

come ottenere il pulsante?

Risposte:


206

Il problema è che il layout incluso non viene considerato come un layout associato a dati. Per farlo agire come uno, devi passare una variabile:

buttons.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}"/>
....

Quindi puoi accedere ai pulsanti indirettamente tramite il campo dei pulsanti:

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

A partire dalla versione 1.0-rc4 (appena rilasciata), non è più necessaria la variabile. Puoi semplificarlo per:

buttons.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 ora risolve il problema di aver bisogno della variabile non necessaria. È ora possibile utilizzare semplicemente: <include layout="@layout/buttons" android:id="@+id/buttons"/>. Hai ancora bisogno dell'ID in modo che produca un campo pubblico per te in modo da poter accedere alla visualizzazione dei pulsanti.
George Mount

1
Qualcun altro ha però problemi ad associare eventi di clic sul layout?
Nilzor,

5
Associazione di dati con supporto include. developer.android.com/topic/libraries/data-binding/…
sowmia

1
Il punto principale da ricordare qui è ottenere il riferimento al pulsante, che devi fare binding.{id of include tag}.buttoninvece di binding.button. Mi ci è voluto un po 'per capirlo.
Rishabh876

1
@NeonWarge C'è un esempio completo su developer.android.com/topic/libraries/data-binding/… . Aggiunge "Il data binding non supporta l'inclusione come figlio diretto di un elemento merge"
Ewan

38

Esempio completo facile

Basta impostare il idlayout incluso e utilizzare binding.includedLayout.anyView.

Questo esempio aiuta a passare un valore <includee ad accedere alle viste incluse nel codice.

Passo 1

Hai layout_common.xml, vuoi passare Stringal layout incluso.

Creerai una Stringvariabile nel layout e la riferirai Stringa TextView.

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

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

Passo 2

Includere questo layout nel layout principale. Dare un idlayout a incluso, in modo che possiamo usarlo nella classe di associazione. Ora puoi passare String passedTextal tuo <includetag.

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>
  • Puoi usarlo ora binding.includedLayout.textViewnella tua classe.
  • Puoi passare qualsiasi variabile al layout incluso come sopra.

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

Nota Entrambi i layout (genitore e incluso) dovrebbero essere binding layoutracchiusi in<layout


Nella tua risposta hai gestito l'evento setText a livello di codice, invece di TextView se fosse stato un pulsante, allora come avresti gestito il suo evento di clic.So che a livello di codice binding.includedLayout.button.setOnClickListenersarebbe l'alternativa, ma cosa succede se voglio usare l' onClickattributo in XML stesso?
iCantC

Puoi passare OnClickListeneral layout incluso. anche tu puoi passare qualsiasi cosa in associazione. Controlla questa risposta, se hai bisogno di ulteriore aiuto, fammelo sapere. stackoverflow.com/a/51722829/6891563
Khemraj

1
Quando lo faccio, ottengo solo un campo vuoto per passedText. L'unica differenza è che non includo il codice MainActivity perché voglio solo passare la risorsa stringa in <include> e lasciarla così. Perché è sempre vuoto però?
Elliptica

3

Un'altra cosa interessante su questo è che puoi passare le variabili al layout importato dal raccoglitore in questo modo:

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

3

Puoi far funzionare il tuo bind sulla tua inclusione semplicemente aggiungendo un ID in questo modo:

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

2

basta impostare un ID per il layout di inclusione

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

poi

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING è res / layout / buttons.xml

adesso :

binding.button.setText("simple_Way");
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.