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?

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

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


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)

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

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");
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.