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" />
我第一次使用我的 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" />