Search code examples
androidrx-javadelayreactivex

How to chain observables with different intervals in RxJava?


I saw a whole lot of posts for having Rx delaying each emission of an event : How to make countdown timer with RxJS Observables?, How to use RxJava Interval Operator, Adding delay between Observable Items RxJava, RxJava delay for each item of list emitted, and others.

Though, I didn't see any for chaining with different delays.

Basically, I have a Textview and a list of letters, and I'd like to :

  • set the text to the first letter
  • wait 1500ms
  • set the text to null
  • wait 500ms
  • set the text to the second letter
  • wait 1500ms
  • set the text to null
  • wait 500ms
  • repeat for the entire list

A code implementation could maybe look somehow like this (but I guess doThing() is nonsense in Rx, and delay() is not meant for this) :

Observable.fromArray(new String[]{"A", "B", "C", "D", "E"})
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .delay(500L, TimeUnit.MILLISECONDS)
        .doThing((String i) -> {
            textView.setText("");
            Log.d("XXX", "MainActivity :: onCreate (110): letter="+ i);
        })
        .delay(1500L, TimeUnit.MILLISECONDS)
        .doThing((String i) -> {
            textView.setText(i);
            Log.d("XXX", "MainActivity :: onCreate (110): letter="+ i);
        });

How can I achieve this with Rx ?

EDIT : I could use the answer from rxjava delay: How to get variable delay on each item emitted from a list? with a list of letters where one letter on two is special (null maybe ?), but it seems overcomplicated.


Solution

  • Sequence: A (1500ms) null (500ms) B (1500ms) null (500ms) C (500ms) null (1500ms)

    textAnimationDisposable = Observable.fromArray("A", "B", "C")
            .concatMap(string ->
                  Observable.merge(
                     Observable.just(string),
                     Observable.just("").delay(1500, TimeUnit.MILLISECONDS)
                  )
                  .concatWith(Observable.<String>empty().delay(500, TimeUnit.MILLISECONDS))
            )
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.newThread())
            .subscribe(string -> textView.setText(string));
    

    The last solution you linked is quite useful for controlling the delay of each item separatly.