我们要观察视图大小的变化,并创建一个如下扩展名:
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侦听器回叫。
如何以及在何处删除布局侦听器回调?
答案 0 :(得分:2)
在处置val MIGRATION_1_2 = object : Migration(1, 2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL(UserSqlUtils().createTable)
}
}
时,您需要删除侦听器。为此,请将Disposable
动作设置为发射器以删除侦听器。
示例
Cancellable
顺便说一句,RxBinding库已经有一个global layout listener的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)
}
}
}