如何将数据从 Adapter 发送到 ViewModel 再到 Fragment

How to send data from Adapter to ViewModel to Fragment

我的结构是这样的,在Fragment中我调用了实例化Adapter

ViewModel

对于我的 RecyclerView 中的每个项目,我都有一个可以收听的按钮

binding.addItem.setOnClickListener(onAddItemClicked(product))

private fun onAddToQuoteClicked(product: Product): View.OnClickListener {
    return View.OnClickListener {
        // TODO add item
    }
}

我不知道如何将这个项目数据发送到片段,有没有办法做到这一点?

我应该在 AdapterViewModel 之间以及 ViewModelFragment 之间使用接口吗?

或者我可以使用 RxEvent & RxBus 吗?

您可以直接通过ViewModel引用添加item并在您的Fragment中订阅RxJava EventBus或LiveData变化或Activity

首先用于 ViewModel 和 Fragment 之间的导航 -

  • 你可以使用 RxJava PublishSubject 制作它 public 并在你的 Fragment 中订阅它,它可以使用 ViewModel 的 public 方法。
  • 或者你可以使用一个接口,在我看来更好的是使用接口你使用更简单的逻辑,在这种情况下错误更少,而且它是更干净的代码,因为你可以根据需要命名接口中的方法 -更容易阅读。

其次是 Adapter 和 Fragment 之间的通信 - 您可以使用与上述相同的策略。在那种情况下,我建议使用 RxJava,因为通常您只需要处理一个或几个点击侦听器(例如,对于发出一些数据对象的 observable)。
如果您需要一些代码示例,请在评论中给我发短信

UPDATE - 更好的做法是在 View 中创建适配器实例,因为我假设您使用的是 MVVM 设计模式(其中所有 UI 相关代码必须是位于视图组件中)。

示例片段 - 适配器通信 Rx - PublishSubject
在您的 适配器

     private val publisher = PublishSubject.create<Product>()
fun getObservableProductItem(): Observable<Product> = publisher.hide()

binding.addItem.setOnClickListener(onAddItemClicked(product))
private fun onAddToQuoteClicked(product: Product): View.OnClickListener {
    return View.OnClickListener {
        publisherRideItem.onNext(items[adapterPosition])
    }
}

override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
    publisherRideItem.onComplete()
}

在你的片段

 compositeDisposable.add(adapter.getObservableProductItem().subscribe {
            //TODO do whatever you want with it
        })   

  override fun onDestroy() {
    super.onDestroy()
    compositeDisposable.clear()
}

RxJava PublishSubject 是最好的选择,我更喜欢它而且非常简单。

我尝试使用 recyclerView - Fragment - ViewModel。有些会有 listadapter -> recyclerVire -> Fragment -> ViewModel。我已经在下面解释了。

列出适配器

在此处指定您的 PublishSubject

class myapadter : ListAdapter
{
 object RxBus {
    val itemClickStream: PublishSubject<View> = PublishSubject.create()
}
}

ViewHolder

在您的 viewHolder 中触发 PublishSubject。

class myViewholder : RecyclerView.ViewHolder(itemView)
{
            itemView.myButton.setOnClickListener {
               v -> RxBus.itemClickStream.onNext(v) }
}

片段

在片段中订阅 PublishSubject,这将自动收到通知。

myapadter.RxBus.itemClickStream.subscribe(){ v ->
            if (v.id == R.id.myButton) {
              viewModel.callyourfunction()
            }