RxBinding源碼解析
此處解析一個Click點擊事件,其他組件大同小異。
RxBinding/rxbinding/src/main/java/com/jakewharton/rxbinding3/view/ViewClickObservable.kt
源碼1:
@file:JvmName("RxView")
@file:JvmMultifileClass
@CheckResult //clicks點擊事件是一個Unit類型Observable事件
fun View.clicks():Observable<Unit> {
//this(也就是當前被點擊View)
return ViewClickObservable(this)
}
//整個方法是一個Unit類型Observable事件
private class ViewClickObservable (private val view:View):Observable<Unit> () {
//此方法在訂閱時被調用,這是一個Unit類型的訂閱者Observer
override fun subscribeActual(observer:Observer<in Unit>){
//不在主線程退出
if (!checkMainThread(observer)) {
return
}
//以當前被點擊View和訂閱者observer創建監聽器
val listener = Listener(view, observer)
//產生一個Disposable,以便取消;Observer.onSubscribe(Disposable disposable)
observer.onSubscribe(listener)
//爲View設置點擊監聽
view.setOnClickListener(listener)
}
//此監聽實現了主線程的onDispose和onClick
private class Listener ( private val view:View,private val observer:Observer<in Unit>
) :MainThreadDisposable(), OnClickListener {
//當Observable.onNext()發射了數據,Observer.onNext()會同步收到數據,這裏表現爲收到點擊事件
override fun onClick(v:View){
if (!isDisposed) {
observer.onNext(Unit)
}
}
//取消監聽
override fun onDispose() {
view.setOnClickListener(null)
}
}
}
源碼2 . 帶xxxEvent的事件類型 由於RxJava只接收一個參數,所以將多參數封裝於xxxEvent
RxBinding/rxbinding/src/main/java/com/jakewharton/rxbinding3/view/ViewScrollChangeEventObservable.kt
@file:JvmName("RxView")
@file:JvmMultifileClass
@RequiresApi(23)
@CheckResult //滾動事件
fun View.scrollChangeEvents(): Observable<ViewScrollChangeEvent> {
return ViewScrollChangeEventObservable(this)
}
//事件類型是ViewScrollChangeEvent
@RequiresApi(23)
private class ViewScrollChangeEventObservable( private val view: View
) : Observable<ViewScrollChangeEvent>() {
override fun subscribeActual(observer: Observer<in ViewScrollChangeEvent>) {
if (!checkMainThread(observer)) {
return
}
val listener = Listener(view, observer)
observer.onSubscribe(listener)
view.setOnScrollChangeListener(listener)
}
private class Listener(
private val view: View,
private val observer: Observer<in ViewScrollChangeEvent>
) : MainThreadDisposable(), OnScrollChangeListener {
//滾動事件封裝的參數
override fun onScrollChange(
v: View,
scrollX: Int,
scrollY: Int,
oldScrollX: Int,
oldScrollY: Int
) {
if (!isDisposed) {
observer.onNext(ViewScrollChangeEvent(v, scrollX, scrollY, oldScrollX, oldScrollY))
}
}
override fun onDispose() {
view.setOnScrollChangeListener(null)
}
}
}