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.