Android-Datenbindung mit Include-Tag


116

Update-Hinweis:

Das obige Beispiel funktioniert ordnungsgemäß , da Release 1.0-rc4 das Problem behoben hat , dass die unnötige Variable benötigt wird.

Ursprüngliche Frage:

Ich mache genau das, was in der Dokumentation beschrieben ist und es funktioniert nicht:

main.xml:

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

button.xml:

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

MyActivity.java:

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

Wie bekomme ich einen Knopf?

Antworten:


205

Das Problem ist, dass das enthaltene Layout nicht als datengebundenes Layout betrachtet wird. Damit es als eine Einheit fungiert, müssen Sie eine Variable übergeben:

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

Dann können Sie indirekt über das Schaltflächenfeld auf Schaltflächen zugreifen:

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

Ab 1.0-rc4 (gerade veröffentlicht) benötigen Sie die Variable nicht mehr. Sie können es vereinfachen, um:

button.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 behebt jetzt das Problem, dass die unnötige Variable benötigt wird. Sie können jetzt einfach verwenden : <include layout="@layout/buttons" android:id="@+id/buttons"/>. Sie benötigen die ID weiterhin, damit ein öffentliches Feld für Sie erstellt wird, damit Sie auf die Schaltflächenansicht zugreifen können.
— George Mount

1
Hat jemand anderes Probleme beim Binden von Klickereignissen im Layout?
— Nilzor

5
Datenbindung mit Include-Unterstützung. developer.android.com/topic/libraries/data-binding/…
— sowmia

1
Der wichtigste Punkt, an den Sie sich hier erinnern sollten, ist das Abrufen der Schaltflächenreferenz, die Sie binding.{id of include tag}.buttonanstelle von ausführen müssen binding.button. Ich habe eine Weile gebraucht, um es herauszufinden.
— Rishabh876

1
@NeonWarge Ein vollständiges Beispiel finden Sie unter developer.android.com/topic/libraries/data-binding/… . Es fügt hinzu "Datenbindung unterstützt nicht Include als direktes untergeordnetes Element eines Zusammenführungselements"
— Ewan

38

Einfaches vollständiges Beispiel

Stellen Sie einfach das identhaltene Layout ein und verwenden Sie es binding.includedLayout.anyView.

In diesem Beispiel können Sie einen Wert an <includeeingeschlossene Ansichten im Code übergeben und auf diese zugreifen.

Schritt 1

Sie haben layout_common.xmlwollen passieren Stringzu enthalten Layout.

Sie erstellen StringVariable im Layout und beziehen sich diese Stringauf TextView.

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

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

Schritt 2

Fügen Sie dieses Layout dem übergeordneten Layout hinzu. Geben Sie ein ideingeschlossenes Layout an, damit wir es in der Bindungsklasse verwenden können. Jetzt können Sie String passedTextan Ihr <includeTag übergeben.

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>
  • Sie können jetzt binding.includedLayout.textViewin Ihrer Klasse verwenden.
  • Sie können beliebige Variablen wie oben beschrieben an das enthaltene Layout übergeben.

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

Hinweis Beide Layouts (übergeordnet und enthalten) sollten mit binding layoutumbrochen werden<layout


In Ihrer Antwort haben Sie das setText-Ereignis programmgesteuert behandelt. Anstelle von TextView, wenn es eine Schaltfläche gewesen wäre, wie hätten Sie dann das Klickereignis behandelt. Ich weiß, dass programmgesteuert binding.includedLayout.button.setOnClickListenerdie Alternative wäre, aber was ist, wenn ich ein onClickAttribut in XML verwenden möchte selbst?
— iCantC

Sie können OnClickListenerzum enthaltenen Layout übergehen . Auch Sie können alles verbindlich übergeben. Überprüfen Sie diese Antwort. Wenn Sie weitere Hilfe benötigen, lassen Sie es mich wissen. stackoverflow.com/a/51722829/6891563
— Khemraj

1
Wenn ich das mache, bekomme ich nur ein leeres Feld für passedText. Der einzige Unterschied besteht darin, dass ich den MainActivity-Code nicht einbinde, weil ich nur die Zeichenfolgenressource in <include> übergeben und so belassen möchte. Warum ist es aber immer leer?
— Elliptica

3

Eine andere interessante Sache dabei ist, dass Sie Variablen aus dem Ordner wie folgt in das importierte Layout einfügen können:

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

3

Sie können festlegen, dass Ihre Bindung an Ihrem Include funktioniert, indem Sie einfach eine ID hinzufügen:

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

2

Legen Sie einfach eine ID für Ihr Include-Layout fest

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

dann

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING ist res / layout / button.xml

jetzt :

binding.button.setText("simple_Way");
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.