当前,我正在处理一个复杂的 recyclerview 布局,其中包含几种不同的模型类型。 为了构建基本结构,我使用了 Airbnb的Epoxy 库。 到目前为止,一切都很好。棘手的部分始于我希望每个单元具有一个单独的ViewModel (来自Android体系结构组件)的那一刻。 每个ViewModel中都有几个可观察对象。
一个非常基本的ViewModel示例:
class ExampleEntryViewModel @Inject constructor(private val exampleRepository: ExampleRepository) : ViewModel() {
private val viewClickedSubject: PublishSubject<String> = PublishSubject.create()
/**
* Inputs
*/
fun viewClicked() {
viewClickedSubject.onNext("example string")
}
/**
* Outputs
*/
fun getPriceValue(): Observable<Float> = exampleRepository.getTicker() // this one pushes data in random intervals
.map { it.price }
fun handleClick(): Observable<String> = viewClickedSubject
}
这里是基本的环氧模型:
@EpoxyModelClass(layout = R.layout.item_example)
abstract class ExampleEntryModel : EpoxyModelWithHolder<ExampleEntryModel.ExampleEntryModelViewModel>() {
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
var onEntryClickListener: EntryClickListener? = null
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
lateinit var viewModel: ExampleEntryViewModel
override fun bind(holder: ExampleEntryModelViewModel) {
holder.apply {
disposables.clear()
disposables += viewModel.output.getPriceValue()
.observeOn(AndroidSchedulers.mainThread())
.subscribe { currentPriceView.text = it }
disposables += viewModel.output.handleClick()
.subscribe { onEntryClickListener?.onEntryClick(clickAction = it) }
rootView.setOnClickListener { viewModel.input.entryClicked() }
}
}
override fun onViewDetachedFromWindow(holder: ExampleEntryModelViewModel) {
holder.disposables.clear()
super.onViewDetachedFromWindow(holder)
}
override fun unbind(holder: ExampleEntryModelViewModel) {
holder.apply {
disposables.clear()
rootView.setOnClickListener(null)
}
super.unbind(holder)
}
interface EntryClickListener {
fun onEntryClick(clickAction: String)
}
class ExampleEntryModelViewModel : EpoxyHolder() {
lateinit var rootView: ConstraintLayout
lateinit var currentPriceView: TextView
val disposables = CompositeDisposable()
override fun bindView(itemView: View) {
rootView = itemView.wrapperMain
currentPriceView = itemView.currentPrice
}
}
}
问题是,有时我的订阅未被订阅或被多次订阅。
达到此目的的最佳方法是在列表中包含多个项(然后可以在一个屏幕上放置更多项),然后快速滚动到列表的底部和顶部。
结果是,某些条目会多次调用handleClick
,而其他条目根本不会调用它们。
我认为问题在于某些订阅不会被处置,而另一些则无法被订阅(或在新订阅后被处置)。
有人知道如何解决吗?如何以正确的方式订阅和处置可观察物?
谢谢。