2017-09-30 8 views
-1

Je ai du mal à comprendre comment utiliser correctement RxBinding, si je veux appeler une demande de réseau quand un utilisateur balaye sur un SwipeRefreshLayout, je m'attendrais à dire quelque chose commeQuelle est la façon idomatic de rafraîchir en utilisant RxBinding sur un SwipeRefreshLayout

RxSwipeRefreshLayout.refreshes(swipeContainer) 
      .flatMap { networkRequest() } 
      .subscribeBy(
        onNext = { list: List<Data> -> Timber.d(data) }, 
        onError = { showErrorSnackbar(it) }, 
        onComplete = { Timber.d("On Complete") }) 

Mais cela ne fonctionne pas pour moi, parce que j'ai que enveloppé dans une fonction appelée setupSwipeRefresh() que j'appelle à onStart, dès que onStart est appelée la demande de réseau est parce que c'est lorsque la mise en page est abonné à.

Maintenant, je ne sais pas quoi faire. Je pourrais juste mettre le tout dans refreshListener mais ce genre de défaites l'objectif de RxBinding.

Ou je pourrais exécuter le networkRequest dans le onNext du swipeContainer. Mais il ressemblerait à quelque chose comme

 RxSwipeRefreshLayout.refreshes(swipeContainer) 
      .subscribeBy(
        onNext = { 
         networkRequest() 
           .subscribeBy(
             onNext = { list: List<Data> -> 
              Timber.d(data) 
             }) 
        }, 
        onError = { showErrorSnackbar(it) }, 
        onComplete = { Timber.d("On Complete") }) 

Mais appeler s'abonner deux fois semble comme un anti-modèle, Alors oui, depuis SwipeRefreshLayout est dans la bibliothèque RxBinding, il doit y avoir un moyen idiomatiques de le faire, parce qu'il semble être le cas d'utilisation le plus courant.

Merci!

Répondre

0

Vous cherchez quelque chose comme ceci:

SwipeRefreshLayout viewById = findViewById(R.id.activity_main_swipe_refresh_layout); 

Observable<State> swipe = RxSwipeRefreshLayout.refreshes(viewById) 
     .map(o -> new IsLoading()); 

Observable<State> stateObservable = Observable.<State>just(new IsLoading()) 
     .mergeWith(swipe) 
     .switchMap(state -> Observable.concat(
       Observable.just(new IsLoading()), 
       Observable.<State>timer(500, TimeUnit.MILLISECONDS) 
         .map(aLong -> new LoadingResult(Collections.emptyList()) 
         ) 
       ) 
     ).distinct(); 

stateObservable 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(
       state -> { 
        if (state instanceof IsLoading) { 
         Log.d("state", "isLoading"); 
        } else if (state instanceof LoadingResult) { 
         Log.d("state", "loadingResult"); 
         viewById.setRefreshing(false); 
        } 
       }); 

Events

interface State { } 

class IsLoading implements State { } 

class LoadingResult implements State { 
    private final List<String> result; 
    public LoadingResult(List<String> result) { 
     this.result = result; 
    } 
} 

SwitchMap est comme FlatMap mais il va passer à la nouvelle observable et jeter les événements incomming de previouse observable.