使用处置处理程序rxjava创建Observable

时间:2019-01-04 19:48:12

标签: android kotlin rx-java2

我们要观察视图大小的变化,并创建一个如下扩展名:

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侦听器回叫。

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

1 个答案:

答案 0 :(得分:2)

在处置val MIGRATION_1_2 = object : Migration(1, 2){ override fun migrate(database: SupportSQLiteDatabase) { database.execSQL(UserSqlUtils().createTable) } } 时,您需要删除侦听器。为此,请将Disposable动作设置为发射器以删除侦听器。

示例

Cancellable

顺便说一句,RxBinding库已经有一个global layout listenerfun 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) } } }