如何使用 MVVM 在 RecyclerView 中监听 onCheckedChangeListener?

How can I listen for onCheckedChangeListener in a RecyclerView using MVVM?

我正在尝试用 Kotlin 编写一个基本的待办事项列表,但想使用推荐的最佳实践和 Android 架构组件。此时我已经设置了基本架构,数据库中存储了一个 RecyclerView 项目列表,左侧有一个复选框,右侧有一个描述。到目前为止,列表会在添加新数据时自动更新(通过浮动操作按钮)。现在我想在单击特定项目的复选框时立即更新记录。

我不知道如何或在何处设置复选框侦听器以便将选中状态和项目 ID 传递给 ViewModel 以更新数据库中的数据。我考虑过直接在适配器内部定义侦听器,但后来我找不到任何方法来调用我的 ViewModel 的更新方法。但是如果我在片段中设置侦听器并将其传递给适配器,我就无法找到获取项目 ID 的方法。

todo list screenshot

这是我当前的片段:

class ChecklistFragment : Fragment() {

    private lateinit var checklistViewModel: ChecklistViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_checklist, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // Set up RecyclerView
        items_list.layoutManager = LinearLayoutManager(activity)
        val adapter = ToDoItemAdapter(object: CompoundButton.OnCheckedChangeListener {
            override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
                Toast.makeText(activity, "checked", Toast.LENGTH_SHORT).show()
            }
        })
        items_list.adapter = adapter

        // Set up ViewModel
        checklistViewModel = ViewModelProviders.of(this).get(ChecklistViewModel::class.java)
        checklistViewModel.allToDoItems.observe(this, Observer { toDoItems ->
            toDoItems?.let { adapter.setToDoItems(it) }
        })

        // Set up fab
        add_list_item_fab.setOnClickListener {
            checklistViewModel.insert(ToDoItem(description = "Item ${Random.nextInt(1,999)}", checked = Random.nextBoolean()))
        }
    }
}

这是我当前的适配器:

class ToDoItemAdapter(val onCheckedChangeListener: CompoundButton.OnCheckedChangeListener) : RecyclerView.Adapter<ToDoItemAdapter.ViewHolder>() {

    private var toDoItems = emptyList<ToDoItem>()

    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val checkbox: CheckBox = view.checkbox
        val tvDescription: TextView = view.tv_description

        fun bind(position: Int) {
            checkbox.isChecked = toDoItems[position].checked
            checkbox.setOnCheckedChangeListener(onCheckedChangeListener)
            tvDescription.text = toDoItems[position].description
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val itemView = LayoutInflater.from(parent.context).inflate(R.layout.checklist_item, parent, false)
        return ViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.bind(position)
    }

    override fun getItemCount() = toDoItems.size

    internal fun setToDoItems(toDoItems: List<ToDoItem>) {
        this.toDoItems = toDoItems
        notifyDataSetChanged()
    }
}

使用 MVVM 架构侦听检查项目并立即将这些更改存储在数据库中的最佳实践方法是什么?

如果您想在 RecyclerView Item 中单击或检查某些内容,

有一种优雅的方法。

class MyAdapter(val viewModel : ViewModel) : RecyclerView.ViewModel<ViewHolder>{

fun onCreateViewModel(..){
     val binding = ItemRecyclerViewBinding.inflate(LayoutInflater.from(parent.context), parent,false)
    binding.vm = viewModel
}
}

在XML

<data>
    <variable name="vm" type="YourViewModel"/
    <variable name="yourItem" type="YourItem"/
</data>
<FrameLayout or something
    android:onClick = "@{(view) -> vm.onClickItem(view, yourItem)}">

</FrameLayout>

在视图模型中 Class,

fun onClickItem(view : View, yourItem : YourItem){
    Log.e(TAG,"$view is clicked with $yourItem")
}

我写了关于如何从 recyclerview 项目中监听点击或检查事件

如果你想知道如何将这些数据存储到数据库中,你可以在 ViewModel 中使用你自己的例程 Class

编码愉快!