0

我使用 BehaviourRelay 作为源 observable,我喜欢它会在订阅时发出最后一个缓存的值,所以我不需要手动调用 showPlayingState(mPlayStateManager.getCurrentState())。

然而,当我想对订阅中的动画做出反应时,这会带来一个问题,因为我不想在这个缓存的发射上运行动画,当我订阅 onCreate 时会发射,UI 应该只是跳转到不对其进行动画处理的状态。动画应该只在“新”发射的情况下运行

这至少对我来说是一个相当常见的用例,但我在 rx 中很难弄清楚

class Activity {

   PlayStateManager mPlayStateManager;
   Button mButton;

   void onCreate(SavedinstanceState state) {
      mPlayStateManager.playState()
        .subscribe(state -> {
           switch(state) {
            case PlayState.PLAYING:
                showPlayingState(true, ???);
                break;
            case PlayState.PAUSED:
                showPlayingState(false, ???);
                break;
           }
        }
   }

   void showPlayingState(boolean isPlay, boolean animate) {
     if(!animate) {
         mButton.setText(isPlay ? "Playing" : "Paused");
     } else {
         mButton.animate()
           .rotate(360)
           .onAnimationEnd(() -> {
              mButton.setText(isPlay ? "Playing" : "Paused");
           })
      }
   }
}


class PlayStateManager {

    BehaviourRelay<PlayState> mSubject = new BehaviourRelay();

    public void set(PlayState state) {
       mSubject.accept(state);
    }

    public Observable<PlayState> playState() {
        return mSubject.hide();
    }
}
4

1 回答 1

0

如果我正确理解了您的问题,那么如果信息较旧,则您不想执行动画playState(),而仅在它切换状态时才执行。换句话说,在最初调用 时onCreate(),您不想做动画,但如果值发生变化,您确实想做动画。

enum PlayStateExpanded {
  UNKNOWN,
  PLAYING,
  PAUSED
}

class PlayStateManager {

    BehaviourRelay<PlayStateExpanded> mSubject = 
       new BehaviourRelay(PlayStateExpanded.UNKNOWN);

    public void set(PlayState state) {
       mSubject.accept(
           state == PlayState.PLAYING ? PlayStateExpanded.PLAYING
                                      : PlayStateExpanded.PAUSED);
    }

    public Observable<PlayStateExpanded> playState() {
        return mSubject.hide();
    }
}

void onCreate(SavedinstanceState state) {
  AtomicBoolean firstTime = new AtomicBoolean(true); // note first time
  mPlayStateManager.playState()
    .subscribe(state -> {
       switch(state) {
        case PlayStateExpanded.PLAYING:
            showPlayingState(true, firstTime.get());
            break;
        case PlayStateExpanded.PAUSED:
            showPlayingState(true, firstTime.get());
            break;
       }
       firstTime.set(false); // no longer first time
    }
}

通过用一个值重新定义播放状态,UNKNOWN简化了启动条件。只需为第一次使用后重置的第一次转换添加一个标志即可实现您的既定目标。

于 2017-10-20T20:43:51.703 回答