ViewBinding - bagaimana cara mendapatkan binding untuk tata letak yang disertakan?

11

Saat bekerja dengan ViewBinding saya menemukan beberapa kasus yang tidak terdokumentasi.

Pertama: Cara mendapatkan penjilidan untuk bagian tata letak tampilan generik yang disertakan, penjilidan utama hanya melihat item di tata letak utama?

Kedua: Cara mendapatkan penjilidan untuk bagian tata letak jenis gabungan yang disertakan, sekali lagi penjilidan utama hanya melihat item di tata letak utama?

Artur Kasprzak
sumber

Jawaban:

15

Dalam hal:

  1. Sertakan dengan tata letak umum (bukan penggabungan simpul), kita perlu menetapkan ID untuk memasukkan bagian, dengan cara ini dalam mengikat kita akan memiliki akses ke sub bagian yang disertakan
<include
    android:id="@+id/your_id"
    layout="@layout/some_layout" />

Dengan cara ini dalam kode aktivitas Anda:

private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    setContentView(exampleBinding.root)
    //we will be able to access included layouts view like this
    val includedView: View = exampleBinding.yourId.idOfIncludedView
//[...]
}
  1. Sertakan dengan blok gabung dalam tata letak eksternal. Kami tidak dapat menambahkan ID ke dalamnya karena blok gabungan bukan tampilan. Katakanlah kita memiliki tata letak gabungan abadi (merge_layout.xm):
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="@layout/activity_example">

    <TextView
        android:id="@+id/some_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World" />
</merge>

Untuk mengikat tata letak gabungan dengan benar, kita perlu:

Dalam kode aktivitas Anda:

private lateinit var exampleBinding: ActivityExampleBinding  //activity_example.xml layout
private lateinit var mergeBinding: MergeLayoutBinding  //merge_layout.xml layout

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    exampleBinding = ActivityExampleBinding.inflate(layoutInflater)
    //we need to bind the root layout with our binder for external layout
    mergeBinding = MergeLayoutBinding.bind(exampleBinding.root)
    setContentView(exampleBinding.root)
    //we will be able to access included in merge layout views like this
    val mergedView: View = mergeBinding.someView
//[...]
}
Artur Kasprzak
sumber
1
Ini seperti bug. Seharusnya berfungsi .
miguel
7

Pertanyaan pertama Anda, yaitu bekerja dengan tata letak yang disertakan menggunakan ViewBinding dapat diselesaikan dengan mudah.

Berikut ini contoh file main_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view_main"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

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

</LinearLayout>

Dan MainFragment.java bisa seperti ini

public class MeaningFragment extends Fragment {

    private MainFragmentBinding binding;
    private ToolbarBinding toolbarBinding;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

        binding = MainFragmentBinding.inflate(inflater, container, false);
        toolbarBinding = binding.toolbar;

        return binding.getRoot();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        toolbarBinding = null;
        binding = null;
    }
}

Sekarang, Anda memiliki dua ikatan. salah satunya adalah default dan yang berikutnya adalah dari tata letak yang disertakan.

Emi Raz
sumber
1
Jawaban yang sangat sederhana dan menggunakan sintaks baru - semuanya bekerja untuk saya dalam Aktivitas non-Fragmen dengan sintaksis serupa di onCreate(). Terima kasih. (Hanya mengalami sedikit kesulitan menggunakan untuk a DrawerLayout)
Fat Monk
0

Cara sederhana lainnya adalah menggunakan pustaka data yang mengikat. Kemudian bungkus tata letak XML Anda dengan tag sehingga jika Anda menggunakan pustaka secara otomatis menghasilkan kelas yang diperlukan untuk mengikat tampilan di tata letak dengan objek data Anda. Jujur, saya pikir itu cara untuk pergi. Ikuti panduannya di sini

Arun Gurung
sumber