Instead of the verbose setOnClickListener
:
RxView.clicks(submitButton).subscribe(o -> log("submit button clicked!"));
Observable
.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.filter(integer -> integer % 2 == 0)
.subscribe(System.out::println);
// => 2, 4, 6, 8, 10
Observable
.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.forEach(System.out::println);
// => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Observable
.just(1, 2, 3, 4, 5)
.groupBy(integer -> integer % 2 == 0).subscribe(grouped -> {
grouped.toList().subscribe(integers -> {
log(integers + " (Even: " + grouped.getKey() + ")");
});
});
// [1, 3, 5] (Even: false)
// [2, 4] (Even: true)
Observable
.just(1, 2, 3, 4, 5)
.take(2)
.subscribe(System.out::println);
// => 1, 2
Observable
.just(1, 2, 3, 4, 5)
.first()
.subscribe(System.out::println);
// => 1
Observable
.just(1, 2, 3, 4, 5)
.last()
.subscribe(System.out::println);
// => 5
Observable
.just(1, 2, 1, 3, 4, 2)
.distinct()
.subscribe(System.out::println);
// => 1, 2, 3, 4
Does not have to emit items of the same type as the source Observable
Observable.just("Hello world!")
.map(s -> s.hashCode())
.subscribe(i -> log(Integer.toString(i)));
// => 121287312
Another map()
can convert it back to String
Observable.just("Hello world!")
.map(s -> s.hashCode())
.map(i -> reverseHashCode(i))
.subscribe(str -> log(str));
// => Hello world!
List<User> users = ArrayList<>();
users.add(new User("jon snow"));
users.add(new User("tyrion lannister"));
Observable
.just(users)
.concatMap(userList -> Observable.from(userList))
.subscribe(user -> log(user.name));
// concatMap: when applied to an item emitted by the source Observable, returns an Observable
// => "jon snow", "tyrion lannister"
RxTextView.textChangeEvents(editText)
.subscribe(e -> log(e.text().toString()));
// => "s"
// => "se"
// => "sea"
// => "sear"
// => "searc"
// => "search"
RxTextView.textChangeEvents(editText)
.filter(e -> e.text.length() >= 3)
.subscribe(e -> log(e.text().toString()));
// => "sea"
// => "sear"
// => "searc"
// => "search"
The submit button only gets enabled if username and password have a length>=3
emailChangeObservable = RxTextView.textChangeEvents(email);
passwordChangeObservable = RxTextView.textChangeEvents(password);
// force-disable the button
submitButton.setEnabled(false);
Observable.combineLatest(emailChangeObservable, passwordChangeObservable,
(emailObservable, passwordObservable) -> {
boolean emailCheck = emailObservable.text().length() >= 3;
boolean passwordCheck = passwordObservable.text().length() >= 3;
return emailCheck && passwordCheck;
}).subscribe(aBoolean -> {
submitButton.setEnabled(aBoolean);
});
// submit button will only be clickable if both forms have more than 3 characters each
Observable
.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.flatMap(this::heavyCalculations)
// all the computation will happen in a background thread
.subscribeOn(Schedulers.computation())
// the result subscription will happen in the UI Thread
.observeOn(AndroidSchedulers.mainThread())
// do the calculations for each item and returns it to the subscribable observer
.subscribe(number -> log(number));
Observable
.just(arrayOfUsers)
.concatMap(users1 -> Observable.from(users1))
.doOnNext(user -> saveToDataBase(user))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
// => saves all the users, one by one in the database, async
Don't know in which thread your code is being executed? Print this method:
Thread.currentThread().getName()
and you'll find out.
All subscribe()
s return a Subscription
object that should be released with a subscription.unsubscribe()
in the activity/fragment lifecycle to prevent memory leaks.
... or if you're lazy like me take a look here https://github.com/trello/RxLifecycle, the guys @trello have created a library that provides automatic unsubscriptions to this kind of events.