android - 使用 dispose handler rxjava 创建 Observable

标签 android kotlin rx-java2

我们想要观察 View 大小的变化,因此我们创建了一个如下的扩展:

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 changed subscribe on $size

但这将继续被调用:

D/MainFragment: ViewTreeObserver Listener called back.

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

最佳答案

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

顺便说一句,RxBinding库已经有 global layout listenerObservable

关于android - 使用 dispose handler rxjava 创建 Observable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54045153/

相关文章:

java - 忽略 Observable<Single<T>> 中的错误

android - 向后兼容的 PageTransformer

java - 如何在android本地数据库中存储intent?

Kotlin:如何使用 JUnit5 和 Mockk 清理或重置模拟

kotlin - IntelliJ 错误 - 无法为初始化脚本打开 init 通用类缓存

android - 我需要在调用 dispose() 之前检查 isDisposed() 吗?

java - 一项 Activity ,多项内容

android - Google Play 商店 : Keep the original release signature

android - 如何在 Kotlin 中引用 "run"或 "apply"内的实现回调

java - RxPermission 在 Release模式下导致内部错误