Android:使用双向数据绑定更新 RecyclerView 列表

Android: Updating RecyclerView list with Two-Way Data Binding

我第一次使用我的 RecyclerView 的双向数据绑定,我对如何将值列表从我的 ViewModel 发送到 RecyclerView 适配器感到困惑

通常我会去我的 Activity/Fragment 做这样的调用来刷新 RecyclerView 列表:

viewModel.getList().observe(viewLifecycleOwner, Observer { list ->
              recyclerView.adapter = adapter(list)
          })

但是由于现在所有事情都在 ViewModel 中完成并跳过 Activity/Fragment,发送列表的最佳方式是什么?

视图模型:

class ViewModel : ViewModel() {

    // This variable is binded to the layout so it has the value of the EditText
    val editTextContent = MutableLiveData<String>()

    // This function is also binded to the layout view
    fun buttonClick() {
        //Here it returns a list that I would send to the adapter
        getList(editTextContent.value.toString())
        // How else can I do this?
    }

    fun getList(search: String): MutableLiveData<List<Object>> = Repository.getList(search)
}

布局XML:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewmodel"
            type="com.example.app.ui.search.FragmentViewModel" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".ui.search.Fragment">

        <EditText
            android:id="@+id/edit_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={viewmodel.editTextContent}"
            android:hint="Name" />

        <Button
            android:id="@+id/search_fragment_search_btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Search"
            android:onClick="@{() -> viewmodel.buttonClick()}"/>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/fragment_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </LinearLayout>
</layout>

我使用自定义属性来做到这一点。
在 viewModel 中创建一个 mutableLiveData 来保存你的列表

    var list = MutableLiveData<List<Object>>()

更改您的 getList 函数以更新列表 mutableLiveData

    fun getList(search: String): MutableLiveData<List<Object>>{
       list.postValue(Repository.getList(search))
    }

我创建了 class 绑定适配器。在BindingAdapter.kt

    @BindingAdapter("listData")
    fun bindRecyclerView(recyclerView: RecyclerView, data: List<Object>) {
        val adapter = recyclerView.adapter as CountryAdapter
        recyclerView.adapter = Adapter(data)
    }

在 Adapter class 中,在 viewholder 中,你应该调用 executePendingBindings

    binding.executePendingBindings()

在XML布局中

     <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/fragment_recycler_view"
                android:layout_width="match_parent"
                listData="@{mainViewModel.list}"
                android:layout_height="match_parent" />