2017-10-20 26 views
0

im BehaviourRelayをソースとして使用すると、サブスクリプション時に最後にキャッシュされた値が放出されるのが好きなので、showPlayingState(mPlayStateManager.getCurrentState())を手動で呼び出す必要はありません。observable emitがキャッシュされたBehaviourSubject値であるかどうかを知る方法?

しかし、これは、onCreateを購読するとエミットされるこのキャッシュされたエミットでアニメーションを実行したくないので、サブスクリプションのアニメーションに反応したいときに問題になります。UIはアニメーション化されない状態にジャンプする必要がありますそれに。アニメーションは、これが私のために少なくともかなり一般的なユースケースですが、私が正しくあなたの質問を理解していればImは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(); 
    } 
} 

答えて

0

でそれを考え出す問題が発生した

を発するだけで「新鮮」の場合に実行する必要がありますplayState()が古い情報であっても、状態が切り替わったときだけ、アニメーションを実行する必要はありません。つまり、onCreate()の最初の呼び出しでは、アニメーションを実行したくないのですが、値が変更された場合はアニメーションを実行する必要があります。 UNKNOWN値で再生状態を再定義することによって

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 
    } 
} 

、起動条件が簡素化されます。初回使用後にリセットされる最初のトランジションのフラグを追加するだけで、あなたの目標が達成されます。

+0

はい、対象はキャッシュされた値なしで空になることがあります – urSus

+0

そして?あなたの質問はそのような場合の行動を説明していませんでした。コードは、値が定義されるのを待っていることを示しました。 –

+0

どういう意味ですか? behaviourrelayは初期のデフォルト値を持たず、thereforceは空であり、thereforceはサブスクライブ時にキャッシュされず、最初の「新鮮な」放出はそれ自体が間違って扱われる。それはあなたが知ってはならないbehaviourrelay、つまりhide()という事実に依存しています。私はおそらく放出されるデータでそれをエンコードすることができますか? – urSus

関連する問題