Android: обновление списка RecyclerView с двусторонней привязкой данных

Я впервые использую двухстороннюю привязку данных к своему RecyclerView и не понимаю, как отправить список значений адаптеру RecyclerView из моего ViewModel.

Обычно я шел к своему Activity/Fragment и делал такой вызов, чтобы обновить список RecyclerView:

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

Но так как сейчас все делается в ViewModel и пропуская Activity/Fragment, как лучше отправить список?

ViewModel:

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>

person efoc    schedule 30.06.2020    source источник
comment
в codelab есть образец: codelabs.developers. google.com/codelabs/. может быть, это поможет вам.   -  person Nguyễn Quang Thọ    schedule 30.06.2020


Ответы (1)


Для этого я использую настраиваемый атрибут.
В viewModel создайте mutableLiveData для хранения вашего списка.

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

Измените функцию getList, чтобы обновить список mutableLiveData

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

Я создаю адаптер привязки класса. В BindingAdapter.kt

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

В классе адаптера в просмотрщике вы должны вызвать 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" />
person Nguyễn Quang Thọ    schedule 30.06.2020