interface OnItemClickListener {
fun onItemClick(position: Int)
}
上記の Listener を Observable に変換したい時に以下の2つのクラスを用いた方法が考えられる。
- Subject<T>
- Observable.OnSubscribe<T>
どちらも問題なさそうだけど確証がない。
RxBinding は Observable.OnSubscribe<T>
を用いた方法で実装されているのは何か理由があるのだろうか。
Subject<T>
を用いた方法には問題があるのだろうか。
以下はそれぞれの方法での実装。
private fun RecyclerView.itemClicks(): Observable<Int> {
val subject = PublishSubject.create<Int>()
val listener = RecyclerViewItemClickListener(this, object : OnItemClickListener {
override fun onItemClick(position: Int) = subject.onNext(position)
})
return subject.doOnSubscribe { this.addOnItemTouchListener(listener) }.doOnUnsubscribe { this.removeOnItemTouchListener(listener) }
}
private fun RecyclerView.itemClicks(): Observable<Int> = Observable.create(RecyclerViewItemClickOnSubscribe(this))
private class RecyclerViewItemClickOnSubscribe(private val recyclerView: RecyclerView) : Observable.OnSubscribe<Int> {
override fun call(subscriber: Subscriber<in Int>) {
val itemClickListener = RecyclerViewItemClickListener(recyclerView, object : OnItemClickListener {
override fun onItemClick(position: Int) {
if (!subscriber.isUnsubscribed) {
subscriber.onNext(position)
}
}
})
recyclerView.addOnItemTouchListener(itemClickListener)
subscriber.add(object : MainThreadSubscription() {
override fun onUnsubscribe() {
recyclerView.removeOnItemTouchListener(itemClickListener)
}
})
}
}