如何从RecyclerViewAdapter调用ViewModel.delete?

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

我想从 Recyclerview 适配器调用 ViewModel.delete(房间数据库)方法,但它不起作用。有什么想法吗?

我想在 OnBindViewHolder 中调用 ViewModel,如下所示: holder.binding.ivItemWalletDelete.setOnClickListener { 钱包视图模型... }

但我收到错误:在空对象上

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
    }
}

ViewModel(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
} 
android kotlin mvvm android-recyclerview viewmodel
2个回答
2
投票

解决此类问题的常见方法是创建一个传递到适配器的回调。

在您的

WalletListAdapter
类中传递一个带有
Wallet
对象的回调。

class WalletListAdapter(private val onDeleteCallback: (Wallet) -> Unit) {}

ViewHolder
中,您可以在每个回收器视图项上设置
OnClickListener
并将
Wallet
对象传递给回调函数。看起来像这样:

binding.root.setOnClickListener { onDeleteCallback(item) }

最后,初始化

WalletListAdapter
的视图(活动、片段等)将传入一个接受
Wallet
对象的函数。然后您可以在此处调用
WalletViewModel
的删除函数。

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
类。重点是将单击事件从适配器“传播”回视图,以便视图可以调用视图模型的方法。


0
投票

清除 Cookie 和缓存可能会让您重新访问调查页面并重新开始。这个方法并不总是有效,但值得一试。

或者,如果调查是在一段时间内进行的,您将来可能会收到另一个邀请链接。请注意您可能收到的有关调查的任何后续电子邮件或通知。

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