如何知道observable emit是否是缓存的BehaviourSubject值?

时间:2017-10-20 18:15:42

标签: android rx-java behaviorsubject

我使用BehaviourRelay作为源可观察源,我喜欢它会在订阅时发出最后一个缓存值,所以我不需要手动调用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();
    }
}

1 个答案:

答案 0 :(得分: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值重新定义播放状态,简化了启动条件。只需为首次使用后重置的第一个转换添加一个标记即可实现您的既定目标。