android - 当点击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)
}
}
解决方案
- 向您的适配器引入一个项目点击回调:
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)
}
}
- 在初始化适配器的片段 onViewCreated() 中处理单击事件
val rvAdapter = AllUsersAdapter(
gitUsersArrayList = gitUsersArrayList, itemClickCallback = fun(status: Boolean) {
navController().navigate(
viewModel.updateValue(status)
)
}
)
- 创建所需的 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 =
}
}
推荐阅读
- android - 如何在不每次都构建的情况下加载路线?
- haskell - 为什么不在 Haskell 中进行类型检查?
- opc-ua - 从服务器获取 ServiceFault 响应
- c++ - 迭代时引用的数组对象不返回类变量 - 在抛出“std::logic_error”的实例后调用终止
- asp.net-mvc-5 - mvc 中的当前上下文中不存在名称“viewbag”
- php - 如何在 PHP 扩展中为每个线程封装全局变量?
- reactjs - 我无法从 ReactJS (SOAP) 中的服务器获取响应。我尝试同时使用 fetch 和 XMLHttpRequest
- c# - 我们如何在 microsoft bot 框架中将用户和机器人消息记录到 comos db
- r - 使用data.table在R中按时间段计算行
- ruby-on-rails - 更新的引导 gem 无法加载到 rails