2017-04-25 114 views
0
組合輸出

問:

哪個運營商或變換我應該用兩個數據流中的代碼量最小,並以最有效的方式結合起來?RxJava - 兩個可觀察人士透露,僅在特定的值

ViewPager,RxBinding,事件流

使用Android ViewPager,我觀察的事件(使用RxBinding)

1)使用onPageSelected(本頁目前可見)

Observable<Integer> pageSelectObs = RxViewPager.pageSelections(mPlaceImageViewPager); 

2)OnPageScrollStateChanged(掃描開始= 1,運動= 2,完成= 0)

Observable<Integer> scrollStateObs = RxViewPager.pageScrollStateChanges(mPlaceImageViewPager); 

整數流是這樣的:

I/System.out: Page: 0 ScrollState: 1 
I/System.out: Page: 0 ScrollState: 2 
I/System.out: Page: 1 ScrollState: 2 
I/System.out: Page: 1 ScrollState: 0 
I/System.out: Page: 1 ScrollState: 1 
I/System.out: Page: 1 ScrollState: 2 
I/System.out: Page: 2 ScrollState: 2 
I/System.out: Page: 2 ScrollState: 0 

我只會在感興趣的:達到

  • ScrollState == ViewPager 0
  • 結束

    當前編號

    這是我當前如何觀察:

    Disposable d = ObservableCombineLatest.combineLatest(pageSelectObs, scrollStateObs, new BiFunction<Integer, Integer, Integer>() { 
        @Override 
        public Integer apply(@NonNull Integer pageSelected, @NonNull Integer scrollState) throws Exception { 
         AUtils.logSystem(TAG, "Page: %s ScrollState: %s", pageSelected, scrollState); 
    
         if (adapter.isLastVisibleItem(pageSelected) && adapter.hasHiddenItemsRight() && scrollState == 0) { 
          return 1; 
         } 
    
         if (adapter.isFirstVisibleItem(pageSelected) && adapter.hasHiddenItemsLeft() && scrollState == 0) { 
          return -1; 
         } 
         return 0; 
        } 
    }).subscribe(new Consumer<Integer>() { 
        @Override 
        public void accept(@NonNull Integer doAction) throws Exception { 
         if (doAction == -1) { 
          AUtils.logSystem(TAG, "shift LEFT"); 
          adapter.shiftLeft(); 
         } 
         if (doAction == 1) { 
          AUtils.logSystem(TAG, "shift RIGHT"); 
          adapter.shiftRight(); 
         } 
        } 
    }); 
    

    有沒有這樣做上面的一個簡單的方法?

+0

爲什麼你檢查:adapter.isLastVisibleItem(pageSelected)&& adapter.hasHiddenItemsRight()? –

+0

我根據頁面更改數據集。 – Baker

回答

1

因爲你的條件很簡單,你可以用一個簡單的filter()運營商表達出來。

Observable<Integer> scrollStateObs = RxViewPager.pageScrollStateChanges(mPlaceImageViewPager) 
     .filter(scrollState -> scrollState == ViewPager.SCROLL_STATE_IDLE); 

爲了只在scrollState變化作出反應,就可以使用withLatestFrom()操作

Disposable d = pageSelectObs.withLatestFrom(scrollStateObs, (pageSelected, scrollState) -> pageSelected) 
     .filter(pageSelected -> adapter.isLastVisibleItem(pageSelected)); 
     .subscribe(pageSelected -> { 
      if (adapter.hasHiddenItemsRight()) { 
       adapter.shiftRight(); 
      } else if (adapter.hasHiddenItemsLeft()) { 
       adapter.shiftRight(); 
      } 
     }); 
+0

正是我在找的東西。謝謝。第一個問題:當濾除除SCROLL_STATE_IDLE之外的滾動狀態時,這將導致ViewPager縮短SETTLING階段並將下一頁捕捉到視圖中(而不是平穩地安置)。想法爲什麼這與過濾流發生,但不與我的原始,粗糙的解決方案? – Baker

+0

第二個問題:'withLatestFrom',BiFunction只是返回pageSelected而不執行其他任何操作,對嗎? (使用RxJava2&我在代碼中沒有使用Lambda語句,有時候我不清楚隱藏什麼) – Baker

+0

1.我並不真正瞭解 2.是的,但是回到那裏並不重要因爲它沒有被使用 – Lamorak

0

那麼'最有效的方式'取決於你的需求和你如何定義最有效的。是時候了,是資源嗎?

我拿了你的代碼,並添加了一個50毫秒的限速窗口,這個突發事件不會經常調用onNext。

在MAP-opreator中,您會爲枚舉添加一些匹配項,因爲-1和1不是代表值。

@Test 
void name() throws Exception { 
    Observable<Integer> pageSelectObs = Observable.just(0, 0, 1, 1, 1, 1, 2, 2); 
    Observable<Integer> scrollStateObs = Observable.just(1, 2, 2, 0, 1, 2, 2, 0); 

    // Test-Obs 
    Observable<ShiftOperation> filter = Observable.combineLatest(pageSelectObs, scrollStateObs, Combined::new) 
      .window(50, TimeUnit.MILLISECONDS) 
      .flatMap(combinedObservable -> combinedObservable.filter(combined -> combined.scrollState == 0) 
        .takeLast(1)) 
      .map(combined -> { 
       // do mapping here 

       return ShiftOperation.SHIFT_LEFT; // do your adapter... check here and decide which operation you want to return. 
      }); 

    filter.test() 
      .await() 
      .assertValueCount(1); 
} 

數據結構:

class Combined { 
    final int pageState; 
    final int scrollState; 

    Combined(int pageState, int scrollState) { 
     this.pageState = pageState; 
     this.scrollState = scrollState; 
    } 
} 

enum ShiftOperation { 
    SHIFT_LEFT, 
    SHIFT_RIGHT 
} 
相關問題