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

问题描述 投票:0回答:1

我正在尝试在Kotlin中编写一个基本的Todo列表,但希望使用推荐的最佳实践和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体系结构监听已检查项目并立即将这些更改存储在数据库中的最佳实践方法是什么?

android mvvm viewmodel
1个回答
1
投票

如果要在RecyclerView项目中单击或检查某些内容,

有一种优雅的方式。

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>

在ViewModel类中,

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

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

如果您想要如何将这些数据存储到DB,可以在ViewModel类中使用您自己的例程

快乐的编码!

© www.soinside.com 2019 - 2024. All rights reserved.