Reputation:
I have a button. If a user presses on it several times, I want it to run a method only when it receives the first click. After the method is finished running and done, I want to listen for button clicks again and do the action only when we receive the first click... ignore the other clicks (continue repeating this). How do I accomplish this with RxJava 2? I don't want to use things along the lines of firstElement() because it will make the button unusable after the first click. Thanks!
Upvotes: 1
Views: 515
Reputation: 4389
Here's an approach that doesn't require a secondary field to track anything, but that doesn't necessarily make it better.
clicks()
is from Jake Wharton's RxBinding library. You can get the Observable
however you like.
button.clicks()
// not strictly necessary, since we disable the button
.filter { button.isEnabled }
.doOnNext { button.isEnabled = false }
.observeOn(Schedulers.computation()) // or io() or whatever
.flatMap { doThing() }
.observeOn(AndroidSchedulers.mainThread())
// `each` instead of `next` so this also consumes errors
.doOnEach { button.isEnabled = true }
.subscribe()
private fun doThing(): Observable<Int> {
// simulate long-running op
Thread.sleep(2000)
// return any value; doesn't matter
return Observable.just(0)
}
Upvotes: 1
Reputation: 29468
Actually, not the best solution, but it can help - you can save state of your action. Something like this:
var isActionDone = true
buttonObservable
.filter { isActionDone }
.flatMap {
isActionDone = false
youActionCompletable
}
.subscribe { isActionDone = true }
Upvotes: 1