diff --git a/rxbinding-material/src/androidTest/java/com/jakewharton/rxbinding3/material/RxBottomNavigationViewTest.java b/rxbinding-material/src/androidTest/java/com/jakewharton/rxbinding3/material/RxBottomNavigationViewTest.java index eac699f7..039b86d2 100644 --- a/rxbinding-material/src/androidTest/java/com/jakewharton/rxbinding3/material/RxBottomNavigationViewTest.java +++ b/rxbinding-material/src/androidTest/java/com/jakewharton/rxbinding3/material/RxBottomNavigationViewTest.java @@ -47,4 +47,20 @@ public final class RxBottomNavigationViewTest { menu.performIdentifierAction(R.id.menu_item_two, 0); o.assertNoMoreEvents(); } + + @Test @UiThreadTest public void itemReselections() { + RecordingObserver o = new RecordingObserver<>(); + RxBottomNavigationView.itemReselections(view).subscribe(o); + + menu.performIdentifierAction(R.id.menu_item_one, 0); + assertEquals(R.id.menu_item_one, o.takeNext().getItemId()); + + menu.performIdentifierAction(R.id.menu_item_one, 0); + assertEquals(R.id.menu_item_one, o.takeNext().getItemId()); + + o.dispose(); + + menu.performIdentifierAction(R.id.menu_item_one, 0); + o.assertNoMoreEvents(); + } } diff --git a/rxbinding-material/src/main/java/com/jakewharton/rxbinding3/material/BottomNavigationViewItemReselectionsObservable.kt b/rxbinding-material/src/main/java/com/jakewharton/rxbinding3/material/BottomNavigationViewItemReselectionsObservable.kt new file mode 100644 index 00000000..a398a839 --- /dev/null +++ b/rxbinding-material/src/main/java/com/jakewharton/rxbinding3/material/BottomNavigationViewItemReselectionsObservable.kt @@ -0,0 +1,54 @@ +@file:JvmName("RxBottomNavigationView") +@file:JvmMultifileClass + +package com.jakewharton.rxbinding3.material + +import android.view.MenuItem +import androidx.annotation.CheckResult +import com.google.android.material.bottomnavigation.BottomNavigationView +import com.jakewharton.rxbinding3.internal.checkMainThread +import io.reactivex.Observable +import io.reactivex.Observer +import io.reactivex.android.MainThreadDisposable + +/** + * Create an observable which emits the reselected item in `view`. + * + * *Warning:* The created observable keeps a strong reference to `view`. Unsubscribe + * to free this reference. + * + */ +@CheckResult +fun BottomNavigationView.itemReselections(): Observable { + return BottomNavigationViewItemReselectionsObservable(this) +} + +private class BottomNavigationViewItemReselectionsObservable( + private val view: BottomNavigationView +) : Observable() { + + override fun subscribeActual(observer: Observer) { + if (!checkMainThread(observer)) { + return + } + val listener = Listener(view, observer) + observer.onSubscribe(listener) + view.setOnNavigationItemReselectedListener(listener) + } + + private class Listener( + private val bottomNavigationView: BottomNavigationView, + private val observer: Observer + ) : MainThreadDisposable(), BottomNavigationView.OnNavigationItemReselectedListener { + + override fun onNavigationItemReselected(item: MenuItem) { + if (!isDisposed) { + observer.onNext(item) + } + } + + override fun onDispose() { + bottomNavigationView.setOnNavigationItemReselectedListener(null) + } + } +} \ No newline at end of file