Pengikatan Data Android menggunakan tag include

116

Perbarui catatan:

Contoh di atas berfungsi dengan baik , karena rilis 1.0-rc4 memperbaiki masalah perlunya variabel yang tidak diperlukan.

Pertanyaan asli:

Saya melakukan persis seperti yang dijelaskan dalam dokumentasi dan tidak berhasil:

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'

bagaimana cara mendapatkan tombol?

Kamil Nekanowicz
sumber

Jawaban:

206

Masalahnya adalah tata letak yang disertakan tidak dianggap sebagai tata letak terikat data. Untuk membuatnya berfungsi sebagai satu, Anda harus meneruskan variabel:

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

Kemudian Anda dapat mengakses tombol secara tidak langsung melalui bidang tombol:

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

Mulai 1.0-rc4 (baru saja dirilis), Anda tidak lagi membutuhkan variabel. Anda dapat menyederhanakannya menjadi:

buttons.xml:

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

main.xml:

<layout xmlns:andr...
...
   <include layout="@layout/buttons"
            android:id="@+id/buttons"/>
....
George Mount
sumber
6
1.0-rc4 sekarang memperbaiki masalah membutuhkan variabel yang tidak perlu. Anda sekarang dapat menggunakan sederhana: <include layout="@layout/buttons" android:id="@+id/buttons"/>. Anda masih membutuhkan id agar dapat menghasilkan bidang publik untuk Anda sehingga Anda dapat mengakses Tampilan Tombol.
George Mount
1
Apakah ada orang lain yang mengalami masalah saat mengikat kejadian klik pada tata letak?
Nilzor
5
Penyatuan data dengan dukungan include. developer.android.com/topic/libraries/data-binding/…
sowmia
1
Hal utama yang perlu diingat di sini adalah mendapatkan referensi tombol, yang perlu Anda lakukan, binding.{id of include tag}.buttonbukan binding.button. Butuh waktu beberapa saat untuk memahaminya.
Rishabh876
1
@NeonWarge Ada contoh lengkapnya di developer.android.com/topic/libraries/data-binding/… . Ia menambahkan "Data binding tidak mendukung penyertaan sebagai turunan langsung dari elemen gabungan"
Ewan
38

Contoh Lengkap Mudah

Cukup atur idke tata letak yang disertakan, dan gunakan binding.includedLayout.anyView.

Contoh ini membantu meneruskan nilai ke <include& mengakses tampilan yang disertakan dalam kode.

Langkah 1

Anda harus layout_common.xml, ingin meneruskan Stringke tata letak yang disertakan.

Anda akan membuat Stringvariabel dalam layout dan merujuknya Stringke TextView.

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

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

Langkah 2

Sertakan tata letak ini ke tata letak induk. Berikan idke layout yang disertakan, agar kita bisa menggunakannya di kelas binding. Sekarang Anda dapat meneruskan String passedTextke <includetag Anda .

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>
  • Anda dapat menggunakannya sekarang binding.includedLayout.textViewdi kelas Anda.
  • Anda dapat meneruskan variabel apa pun ke tata letak yang disertakan seperti di atas.

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

Catatan Kedua tata letak (induk & disertakan) harus binding layoutdibungkus dengan<layout

Khemraj
sumber
Dalam jawaban Anda, Anda menangani acara setText secara terprogram, Alih-alih TextView jika itu akan menjadi Tombol, lalu bagaimana Anda menangani peristiwa kliknya. Saya tahu bahwa secara terprogram binding.includedLayout.button.setOnClickListenerakan menjadi alternatif, tetapi bagaimana jika saya ingin menggunakan onClickatribut dalam XML diri ?
iCantC
Anda bisa lolos OnClickListenerke tata letak yang disertakan. bahkan Anda dapat memberikan apa pun dalam penjilidan. Periksa jawaban ini, jika Anda butuh bantuan lebih lanjut, beri tahu saya. stackoverflow.com/a/51722829/6891563
Khemraj
1
Ketika saya melakukan ini, saya hanya mendapatkan bidang kosong untuk passedText. Satu-satunya perbedaan adalah saya tidak menyertakan kode MainActivity karena saya hanya ingin meneruskan sumber daya string di <include> dan membiarkannya seperti itu. Kenapa selalu kosong?
Elliptica
3

Hal menarik lainnya adalah Anda dapat memasukkan variabel ke layout yang diimpor dari binder seperti ini:

MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.setVariable(BR.varID, variable)
Cosmin Constantin Firta
sumber
3

Anda dapat membuat pengikatan Anda berfungsi pada penyertaan Anda hanya dengan menambahkan ID ke dalamnya seperti:

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

cukup setel id untuk tata letak include Anda

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

kemudian

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING adalah res / layout / buttons.xml

sekarang :

binding.button.setText("simple_Way");
Sadeq Hitex
sumber