我正在使用带有Room,LiveData,带有ListAdapter和数据绑定的RecyclerView的MVVM创建待办事项应用程序。当我检查一个项目时,它跳到列表的底部(按不完整排序,然后完成)。我还对完成的项目使用了不同的布局,其中文本变为斜体并显示为灰色。通常,当我选中一个框时,它会跳下并变成灰色/斜体,但有时会保持黑色。如何找到这个问题,或者数据绑定库可能有问题?
// ToDoItemAdapter.kt
const val ITEM_UNCHECKED = 0
const val ITEM_CHECKED = 1
class ToDoItemAdapter(private val onCheckboxClick: (ToDoItem) -> Unit, private val onCardClick: (ToDoItem) -> Unit): ListAdapter<ToDoItem, RecyclerView.ViewHolder>(ToDoItemDiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ITEM_CHECKED -> ViewHolderChecked.from(parent)
else -> ViewHolderUnchecked.from(parent)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is ViewHolderChecked -> {
val toDoItem = getItem(position)
holder.bind(toDoItem, onCheckboxClick, onCardClick)
}
is ViewHolderUnchecked -> {
val toDoItem = getItem(position)
holder.bind(toDoItem, onCheckboxClick, onCardClick)
}
}
}
override fun getItemViewType(position: Int): Int {
val toDoItem = getItem(position)
return when (toDoItem.completed) {
true -> ITEM_CHECKED
false -> ITEM_UNCHECKED
}
}
class ViewHolderChecked private constructor(private val binding: ChecklistItemCheckedBinding)
: RecyclerView.ViewHolder(binding.root) {
fun bind(toDoItem: ToDoItem, onCheckboxClick: (ToDoItem) -> Unit, onCardClick: (ToDoItem) -> Unit) {
binding.todoItem = toDoItem
binding.checkboxCompleted.setOnClickListener {
onCheckboxClick(toDoItem)
}
binding.cardTodo.setOnClickListener {
onCardClick(toDoItem)
}
binding.executePendingBindings()
}
companion object {
fun from(parent: ViewGroup): ViewHolderChecked {
val layoutInflater = LayoutInflater.from(parent.context)
return ViewHolderChecked(ChecklistItemCheckedBinding.inflate(layoutInflater, parent, false))
}
}
}
在适配器中,单击复选框后,它会在视图模型中运行一个函数:
fun toggleCheckbox(toDoItem: ToDoItem) {
toDoItem.completed = !toDoItem.completed
update(toDoItem)
}
update(toDoItem)调用暂停函数,并基本上通过后台线程上的存储库更新Room数据库中的数据。
在片段中,我将绑定设置为与viewmodel相等,设置生命周期所有者,设置适配器,然后在allToDoItems列表上设置观察者:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
binding.checklistViewModel = checklistViewModel
binding.lifecycleOwner = this
val adapter = ToDoItemAdapter(onCheckboxClickHandler, onCardClickHandler)
binding.itemsList.adapter = adapter
checklistViewModel.allToDoItems.observe(viewLifecycleOwner, Observer { allItems ->
allItems?.let {
adapter.submitList(allItems.sortedWith(compareBy(
{it.completed},
{it.description}))
)
}
})
return binding.root
}