使用dispose处理程序rxjava创建Observable



我们想观察视图大小的变化,我们创建了一个这样的扩展:

fun View.layoutSizeObservable(): io.reactivex.Observable<Size> {
return io.reactivex.Observable.create<Size> { emitter ->
viewTreeObserver.addOnGlobalLayoutListener {
Log.d("MainFragment", "ViewTreeObserver Listener called back.")
if (measuredWidth > 0 && measuredHeight > 0) {
emitter.onNext(Size(measuredWidth, measuredHeight))
}
}
}
}

然后我们这样使用它,它的功能很好:

sizeChangedDisposable = titleTextView.layoutSizeObservable().subscribe { size: Size ->
Log.d("MainFragment", "Size changed subscribe on $size")
}

然而,有一件事并不是我们想要的,那就是Listener是通过addOnGlobalLayoutListener添加的,但从未删除。

我们可以调用sizeChangedDisposable.dispose(),它将正确停止订阅:

D/MainFragment:在$Size 上订阅的大小已更改

但这将继续被称为:

D/MainFragment:ViewTreeObserver侦听器回调。

如何以及在哪里删除布局侦听器回调?

在处理Disposable时,需要删除侦听器。要做到这一点,请将Cancellable操作设置为发射器,移除侦听器。

示例

fun View.layoutSizeObservable(): io.reactivex.Observable<Size> {
return io.reactivex.Observable.create<Size> { emitter ->
val listener = ViewTreeObserver.OnGlobalLayoutListener {
Log.d("MainFragment", "ViewTreeObserver Listener called back.")
if (measuredWidth > 0 && measuredHeight > 0) {
emitter.onNext(Size(measuredWidth, measuredHeight))
}
}
viewTreeObserver.addOnGlobalLayoutListener(listener)
emitter.setCancellable {
Log.d("MainFragment", "ViewTreeObserver Listener removed.")
viewTreeObserver.removeOnGlobalLayoutListener(listener)
}
}
}

BTW,RxBinding库已经有一个用于全局布局侦听器的Observable

最新更新