2017-11-18 5 views
0

私は、ユーザがビューを押し続けている間に繰り返しイベントを生成するオブザーバブルを作成しようとしています。下のコードはうまく動作しますが、初めての場合(ユーザーがボタンをもう一度押すと、何も起こりません)。私は間違って何をしているのかアドバイスしてもらえますか?これには何がベストプラクティスですか?RxJavaボタンが押されたときに繰り返されるイベントを生成するために観測可能

val touches = RxView.touches(previousButton) 
touches 
     .filter({ event -> event.action == MotionEvent.ACTION_DOWN }) 
     .flatMap({ 
      Observable.interval(500, 50, TimeUnit.MILLISECONDS) 
        .takeUntil(touches.filter({event -> event.action == MotionEvent.ACTION_UP})) 
     }).subscribe({ println("down") }) 

答えて

0

問題は、1つ以上のソースについて観察可能なRxView.touchesが存在しないことです。これは、flatMapのサブスクリプションが発生したときに、flatMapをトリガするために使用された元のサブスクリプションを破棄し、再度発生しないことを意味します。

  1. 使用.publish(...)ではなくtouchesを使用してのイベントのソースを共有する:

    この周りの2つの方法があります。

  2. イベントをオン/オフ観測可能にBooleanにマッピングし、次にswitchMapにオブザーバブルの現在の値に基づいて適切なアクションを割り当てます。

1.

touches.publish { src -> 
    src.filter(...) 
     .flatMap { 
      Observable.interval(...) 
        .takeUntil(src.filter(...)) 
     } 
} 

2.

touches.filter { 
      it.action == MotionEvent.ACTION_DOWN 
       or it.action == MotionEvent.ACTION_UP 
     } 
     .map { it.action == MotionEvent.ACTION_DOWN } 
     .distinctUntilChanged() // Avoid repeating events 
     .switchMap { state -> 
      if (state) { 
       Observable.interval(...) 
      } else { 
       Observable.never() 
      } 
     } 
+0

第2の方法は、私のために働いたので、私はそれを受け入れるつもりです。私は興味がありますが、なぜ私は最初のトウ作業を自動接続でも行えないのですか?以下は、動作しなかったコードです: '' 'touches.publish()。autoConnect(2).let {sharedTouches - > sharedTouches.filter({event-> event.action == MotionEvent.ACTION_DOWN}) 。 flatMap({ Observable.interval(....) .takeUntil(sharedTouches.filter({イベント - > event.action == MotionEvent.ACTION_UP})) })。購読(...)} ' '' –

+0

2つの内部サブスクリプションの後でのみサブスクライブしますが、セカンダリサブスクリプションは最初のサブスクリプションが何かを発行した後にのみ発生します。だから、決して起こらないサブスクリプションを待つデッドロックに終わる。 – Kiskae

関連する問題