2014-11-18 1 views
1

Я пытался реализовать многошаговый мастер использования в RxJava. Чтобы упростить этот случай, предположим, что пользователи могут перейти только к следующему шагу, но не назад.Как реализовать многоэтапный мастер в RxJava?

Я думал моделировать каждый шаг как наблюдаемый, который будет отображаться при подписке и будет завершен, когда пользователь решит перейти к следующему шагу. Так что будет step1_Observable, step2_Observable и т.д.

Тогда логика контроллера мастера будет идти, как 1) подписаться на step1_Observable 2), когда step1_Observable завершается, подписываться на step2_Observable 3), когда step2_Observable завершается, подписываться на step3_Observable и так далее.

Можно было бы подумать, почему я не могу просто моделировать следующее событие нажатия кнопки шага в качестве наблюдаемого и подписаться на него, чтобы сделать следующий шаг. Причина в том, что в моем дизайне каждый шаг будет иметь свой собственный уникальный метод для перехода на следующую страницу. Например, это может быть особый жест на сенсорном экране или даже правильно ответить на викторину.

Я не мог понять, как я могу достичь этого с помощью операций, предоставляемых Rx. Есть идеи?

ответ

1

flatMap Используется для запуска Observable s на заказ. Вот пример, чтобы показать, как запустить наблюдаемый после некоторых наблюдаемых Завершает:

public Observable<String> step1() { 
    return null; 
} 

public Observable<String> step2() { 
    return null; 
} 

public Observable<String> step3() { 
    return null; 
} 

public Observable<String> chainSteps(final Observable<String> first, final Observable<String> second) { 
    return first.flatMap(new Func1<String, Observable<String>>() { 

     @Override 
     public Observable<String> call(String s) { 
      return Observable.empty(); 
     } 
    }, new Func1<Throwable, Observable<String>>() { 

     @Override 
     public Observable<String> call(Throwable e) { 
      return Observable.error(e); 
     } 
    }, new Func0<Observable<String>>() { 

     @Override 
     public Observable<String> call() { 
      return second; 
     } 
    }); 
} 

public void example() { 
    chainSteps(chainSteps(step1(), step2()), step3()).subscribe(...); 
} 

Вы также можете использовать Transformer, чтобы сделать коды более многоразовыми.

public class ChainTransformer<T> implements Observable.Transformer<T, T> { 

    private final Observable<T> other; 

    public ChainTransformer(Observable<T> other) { 
     this.other = other; 
    } 

    @Override 
    public Observable<? extends T> call(Observable<? extends T> observable) { 
     return observable.flatMap(new Func1<T, Observable<T>>() { 

      @Override 
      public Observable<T> call(T s) { 
       return Observable.empty(); 
      } 
     }, new Func1<Throwable, Observable<T>>() { 

      @Override 
      public Observable<T> call(Throwable e) { 
       return Observable.error(e); 
      } 
     }, new Func0<Observable<T>>() { 

      @Override 
      public Observable<T> call() { 
       return other; 
      } 
     }); 
    } 
} 

public void example() { 
    step1().compose(new ChainTransformer<String>(step2())) 
      .compose(new ChainTransformer<String>(step3())); 
} 
+0

Спасибо за решение. Я не знал, что существует вариант flatMap, который позволяет вернуть новый наблюдаемый в onComplete callback. Рад узнать этот совет. Есть только одна вещь, которая мне не особенно нравится в вашем решении: нам нужно вложить вызов chainSteps. Если будет неуклюже, когда у нас будет больше шагов, чем 3. Не уверен, есть ли лучшее решение. – xwk

+0

Я обновил ответ. Вы можете использовать 'compose' и' Transformer' для очистки кода. – zsxwing