Reputation: 641
I am using two way data binding with my RecyclerView
for the first time and I am confused on how to send the list of values to the RecyclerView
adapter from my ViewModel
Usually I would go to my Activity/Fragment
and do a call like this to refresh the RecyclerView
list:
viewModel.getList().observe(viewLifecycleOwner, Observer { list ->
recyclerView.adapter = adapter(list)
})
But since everything is being done in the ViewModel
now and skipping over the Activity/Fragment
, what would be the best way to send the list over?
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)
}
Layout 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>
Upvotes: 1
Views: 2351
Reputation: 201
I use custom attribute to do that.
In viewModel create a mutableLiveData to hold your list
var list = MutableLiveData<List<Object>>()
Change your getList Function to update list mutableLiveData
fun getList(search: String): MutableLiveData<List<Object>>{
list.postValue(Repository.getList(search))
}
I create class binding adapter. In BindingAdapter.kt
@BindingAdapter("listData")
fun bindRecyclerView(recyclerView: RecyclerView, data: List<Object>) {
val adapter = recyclerView.adapter as CountryAdapter
recyclerView.adapter = Adapter(data)
}
In Adapter class, in viewholder, you should call executePendingBindings
binding.executePendingBindings()
In XML layout
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/fragment_recycler_view"
android:layout_width="match_parent"
listData="@{mainViewModel.list}"
android:layout_height="match_parent" />
Upvotes: 1