此活动的UI有四个可以选择的按钮,当它们被选中时应呈现蓝色,而在未选择时应呈灰色。
配置现在是具有单个项目类型的RecyclerView,其中包含所有4个按钮:
<ConstraintLayout>
<LinearLayout
android:id="button1"
background="@{viewModel.bgColor1}"... />
<LinearLayout
android:id="button2"
background="@{viewModel.bgColor2}"... />
<LinearLayout
android:id="button3"
background="@{viewModel.bgColor3}"... />
<LinearLayout
android:id="button4"
background="@{viewModel.bgColor4}"... />
注意:文本颜色也是动态数据绑定的。
MyAdapter(
config: AsyncDifferConfig<PartItemLifecycleModel>
): ListAdapter<MyModel, MyViewHolder<MyModel>>(config) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
MyViewHolder(layoutInflator.inflate(R.layout.my_layout, parent, false))
override fun onBindViewHolder(holder: MyViewHolder<MyModel>, position: Int) {
holder.bindViewModel(items[i])
}
}
class MyViewHolder(itemView: ViewGroup): RecyclerView.ViewHolder(itemView) {
fun bindViewModel(viewModel: MyModel) {
rootLayout?.let { layout ->
binding = DataBindingUtil.bind<MyLayoutBinding>(layout)?.also {
it.viewModel = viewModel
}
}
}
}
每当我重新绑定新的视图模型时,整个视图层次结构都会重新呈现并引起视觉闪烁。
我尝试过的另一种方法是让每个MyViewModel
均等地比较(实现equals
/ hashCode
,以便它们始终彼此匹配)并强制RecyclerView
重新使用单个ViewModel
。这有些起作用,但是直到再次按下按钮,UI(通过android数据绑定)才会更新。换句话说,选择按钮1时,选择按钮2不会更新视图以反映该视图,直到按下按钮3为止。当按下button-3时,UI会更新以反映按钮2的按下,而不是按钮3。
尚未实现的第三种方法是将每个按钮实现为单独的RecyclerView类型,并正确实现equals
/ hashCode
。不幸的是,RecyclerView的布局管理器似乎只允许垂直项目,每个项目都占据所有水平空间和可变的垂直空间,反之亦然。