android - 如何从 RecyclerView 适配器调用 ViewModel.delete?
问题描述
我想从我的 Recyclerview 适配器调用我的 ViewModel.delete(房间数据库)方法,但它不起作用。有任何想法吗?
我想在 OnBindViewHolder 中调用 ViewModel,例如: holder.binding.ivItemWalletDelete.setOnClickListener { WalletViewModel... }
但我得到了错误:在一个空对象上
RecyclerView 适配器 (WalletListAdapter.kt)
class WalletListAdapter:
ListAdapter<Wallet, WalletListAdapter.ViewHolder>(WalletDiffCallback()){
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): ViewHolder {
return ViewHolder.from(parent)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)
}
class ViewHolder private constructor(val binding: ItemWalletsBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Wallet) {
binding.wallet = item
binding.executePendingBindings()
}
companion object {
fun from(parent: ViewGroup): ViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = ItemWalletsBinding.inflate(layoutInflater, parent, false)
return ViewHolder(binding)
}
}
}
}
class WalletDiffCallback : DiffUtil.ItemCallback<Wallet>() {
override fun areItemsTheSame(oldItem: Wallet, newItem: Wallet): Boolean {
return oldItem.walletId == newItem.walletId
}
override fun areContentsTheSame(oldItem: Wallet, newItem: Wallet): Boolean {
return oldItem == newItem
}
}
视图模型 (WalletViewModel.kt)
class WalletViewModel(application: Application): AndroidViewModel(application) {
private val repository = WalletRepository(application)
private val liveWalletList = repository.getLiveDataWallets()
fun insert(wallet: Wallet){
viewModelScope.launch {
repository.insert(wallet)
}
}
fun update(wallet: Wallet){
viewModelScope.launch {
repository.update(wallet)
}
}
fun delete(wallet: Wallet){
viewModelScope.launch {
repository.delete(wallet)
}
}
fun getWalletById(walletId: Long): Wallet? {
var wallet: Wallet? = null
viewModelScope.launch {
wallet = repository.getWalletById(walletId)
}
return wallet
}
fun getAllWallets(): List<Wallet>? {
var wallets: List<Wallet>? = null
viewModelScope.launch {
wallets = repository.getAllWallets()
}
return wallets
}
fun getLiveWalletList(): LiveData<List<Wallet>> = liveWalletList
}
解决方案
解决此类问题的一种常见方法是创建一个回调,该回调将传递给适配器。
在你的WalletListAdapter
类中传入一个接受Wallet
对象的回调。
class WalletListAdapter(private val onDeleteCallback: (Wallet) -> Unit) {}
您ViewHolder
可以OnClickListener
在每个回收站视图项上设置一个并将Wallet
对象传递给回调函数。看起来像这样:
binding.root.setOnClickListener { onDeleteCallback(item) }
最后,初始化 的视图(活动、片段等)WalletListAdapter
将传入一个接受Wallet
对象的函数。然后在这里调用WalletViewModel
's delete 函数。
class WalletListActivity: Activity() {
@Inject
lateinit var viewModel: WalletViewModel
override fun onCreate(bundle: Bundle?) {
super.onCreate(savedInstanceState)
// initialize the WalletListAdapter and pass in the callback
val adapter = WalletListAdapter(::deleteWallet)
}
private fun deleteWallet(wallet: Wallet) {
viewModel.delete(wallet)
}
}
注意:你可以先WalletListAdapter
用一个空的构造函数初始化类,然后创建一个方法,将视图的回调函数传递给WalletListAdapter
类。关键是将点击事件从适配器“传播”回视图,因此视图可以调用视图模型的方法。
推荐阅读
- ninject - 在请求范围内,在 Ninject InterceptAttribute 和 ApiController 之间共享相同的实例
- python - cnn+lstm 模型的预测在尝试其他视频时总是显示相同的结果
- c# - 为什么我的数据被传递到部分,但它没有显示?
- javascript - 给反应中的动态数组元素一个图标
- cuda - 在 Conda 环境中升级 Cuda 10.2 的问题
- laravel - Laravel + vue.js ,与 db 数据同步?
- splunk - splunk 按日志事件中的大小列对事件进行排序
- java - 反映环境变量重新加载到java bean
- reactjs - 使用 GitHub Actions 运行 npm run build 时找不到依赖项
- sql - 如何将垂直结果显示为水平