首页 > 解决方案 > 当点击recyclerview项目时如何更新viewModel的实时数据

问题描述

我是 Kotlin 的新手,我正在尝试使用 MVVM 创建一个应用程序。所以我想做的是在存储库中使用改造进行网络调用并将数据返回到视图模型,然后观察片段中的数据,一旦数据发生变化,我就会将它通知给回收器视图适配器一切都是工作正常。现在,问题是我想从 recyclerview 更新 ViewHolder 的实时数据。当我单击 recyclerView 中的 CheckBox 时,应更新数据。但我不知道这样做的实际方法是什么。

这是我的 ViewHolder。

class MainActivityViewModel : ViewModel() {

private var mutableLiveGitUsers: MutableLiveData<ArrayList<GitUsers>>? = null
private lateinit var gitUsersRepository: GitUsersRepository
var allUsersListener: AllUsersListener? = null

fun init() {

    gitUsersRepository = GitUsersRepository()
    allUsersListener?.onStarted()
    mutableLiveGitUsers = gitUsersRepository.getGitUsers()
    allUsersListener?.onSuccess(mutableLiveGitUsers!!)
}

fun getGitUsersData(): MutableLiveData<ArrayList<GitUsers>>? {
    return mutableLiveGitUsers
}

}

这是我观察片段变化的方式

mutableLiveGitUsers.observe(this, Observer {
        progressBar.hide()
        rvAllUsersAdapter = AllUsersAdapter(mainActivityViewModel.getGitUsersData()?.value!!)
        rvAllUsers.adapter = rvAllUsersAdapter
        rvAllUsersAdapter.notifyDataSetChanged()
    })

RecyclerView 适配器

class AllUsersAdapter(private var gitUsersArrayList: ArrayList<GitUsers>) :
RecyclerView.Adapter<AllUsersAdapter.AllUsersViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AllUsersViewHolder {
    val inflater: LayoutInflater = LayoutInflater.from(parent.context)
    val v: View = inflater.inflate(R.layout.items_all_users, parent, false)
    return AllUsersViewHolder(v)
}

override fun getItemCount(): Int {
    return gitUsersArrayList.size
}

override fun onBindViewHolder(holder: AllUsersViewHolder, position: Int) {

    holder.tvUserName.text = gitUsersArrayList[position].login

    Glide.with(holder.itemView.context)
        .load(gitUsersArrayList[position].avatarUrl)
        .centerCrop()
        .into(holder.imageView)

    holder.checkBox.isSelected = gitUsersArrayList.get(position).isSelected

    holder.checkBox.setOnCheckedChangeListener{compoundButton, isChecked ->

        if (isChecked){
    /* Here I want to change the live data so I can observe that changes in my 
fragment and can have an effect in UI*/

            Log.d("TESTC","AllUsersAdapter IsChecked")
        }else{
            Log.d("TESTC","AllUsersAdapter UnChecked")
        }
    }

}

class AllUsersViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    var tvUserName: TextView = itemView.findViewById(R.id.tvUserName)
    var imageView: ImageView = itemView.findViewById(R.id.imageView)
    var checkBox: CheckBox = itemView.findViewById(R.id.checkBox)
}
}

标签: androidkotlinandroid-recyclerviewandroid-livedataandroid-mvvm

解决方案


  1. 向您的适配器引入一个项目点击回调:
class AllUsersAdapter(private var gitUsersArrayList: ArrayList<GitUsers>,
 private val itemClickCallback: ((Boolean) -> Unit)?) :
RecyclerView.Adapter<AllUsersAdapter.AllUsersViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AllUsersViewHolder {
    val inflater: LayoutInflater = LayoutInflater.from(parent.context)
    val v: View = inflater.inflate(R.layout.items_all_users, parent, false)
    return AllUsersViewHolder(v)
}

override fun getItemCount(): Int {
    return gitUsersArrayList.size
}

override fun onBindViewHolder(holder: AllUsersViewHolder, position: Int) {

    holder.tvUserName.text = gitUsersArrayList[position].login

    Glide.with(holder.itemView.context)
        .load(gitUsersArrayList[position].avatarUrl)
        .centerCrop()
        .into(holder.imageView)

    holder.checkBox.isSelected = gitUsersArrayList.get(position).isSelected

    holder.checkBox.setOnCheckedChangeListener{compoundButton, isChecked ->

        if (isChecked){
    /* Here I want to change the live data so I can observe that changes in my 
fragment and can have an effect in UI*/

            Log.d("TESTC","AllUsersAdapter IsChecked")
 itemClickCallback?.invoke(true)
        }else{
            Log.d("TESTC","AllUsersAdapter UnChecked")
 itemClickCallback?.invoke(false)
        }
    }

}

class AllUsersViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    var tvUserName: TextView = itemView.findViewById(R.id.tvUserName)
    var imageView: ImageView = itemView.findViewById(R.id.imageView)
    var checkBox: CheckBox = itemView.findViewById(R.id.checkBox)
}
}
  1. 在初始化适配器的片段 onViewCreated() 中处理单击事件
 val rvAdapter = AllUsersAdapter(
            gitUsersArrayList = gitUsersArrayList, itemClickCallback = fun(status: Boolean) {
                navController().navigate(
                    viewModel.updateValue(status)
                )
            }
        )

  1. 创建所需的 ViewModel 函数:
class MainActivityViewModel : ViewModel() {

private var mutableLiveGitUsers: MutableLiveData<ArrayList<GitUsers>>? = null
private lateinit var gitUsersRepository: GitUsersRepository
var allUsersListener: AllUsersListener? = null

fun init() {

    gitUsersRepository = GitUsersRepository()
    allUsersListener?.onStarted()
    mutableLiveGitUsers = gitUsersRepository.getGitUsers()
    allUsersListener?.onSuccess(mutableLiveGitUsers!!)
}

fun getGitUsersData(): MutableLiveData<ArrayList<GitUsers>>? {
    return mutableLiveGitUsers
}

fun updateValue(status: Boolean) {
//@Todo Set new value based on status received
     // mutableLiveGitUsers.value = 
}
}

推荐阅读