2015-07-08 17 views
6

Tak więc kilka tygodni temu zadałem to pytanie: recyclerview periodic ui child updates.Używanie RxJava wewnątrz adaptera RecyclerView

A dziś chcę, aby tę funkcję zastąpić za pomocą Rxjava. W rzeczywistości jest to bardzo proste, wykonuję się w następujący sposób:

@Override 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 

       if (friend.getGameStatus().equals(GameStatus.INGAME)) { 
        holderOnline.startRepeatingTask(); 
       } else { 
        holderOnline.stopRepeatingTask(); 
       } 
    } 


class MyViewHolderOnline extends RecyclerView.ViewHolder { 

    private Subscription subscribe; 

     public MyViewHolderOnline(View itemView) { 
      super(itemView); 
      ButterKnife.bind(this, itemView); 

     } 

     public void startRepeatingTask() { 
      subscribe = Observable.interval(updateInterval, TimeUnit.MILLISECONDS) 
        .map(aLong -> current.getGameStatusToPrint()) 
        .subscribeOn(Schedulers.io()) 
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(new Subscriber<String>() { 
         @Override public void onCompleted() { } 
         @Override public void onError(Throwable e) { } 

         @Override 
         public void onNext(String gameStatusToPrint) { 
          gameStatus.setText(gameStatusToPrint); 
         } 
        }); 
     } 

     void stopRepeatingTask() { 
      if(subscribe != null && !subscribe.isUnsubscribed()) 
       subscribe.unsubscribe(); 
     } 
    } 

Problem jest jednak inny. Mam nawigacjęDrawer zaimplementowaną z Aktywnościami, które są wstrzymane i nie są niszczone po przełączeniu. Tak więc, po przejściu na działanie, które nie zawiera tego adaptera, obserwowalne wysyła dalej rzeczy, ponieważ jest to okresowa przerwa Obserwowalna. Moje pytanie brzmi: co powinienem zrobić? Muszę zrezygnować z subskrypcji, gdy działanie zostało wstrzymane, ale nie mam pojęcia, od kiedy, a także jak zasubskrybować z powrotem. Jakaś pomoc lub pomysły?

+0

czy powinienem dokonać sprawdzenia onNext i nic nie robić, jeśli działanie zostało wstrzymane? –

Odpowiedz

1

Tak więc, jeśli cię rozumiem poprawnie, jednym ze sposobów rozwiązania tego problemu jest odpowiedź na pytanie: w Activity że zawiera RecyclerView, jak mogę dostać odniesień do wszystkich ViewHolder s, które są aktualnie wyświetlane/zmierzały?

Na przykład, aby zatrzymać wszystkie aktualizacje można wykonaj następujące czynności w onPause() twoich Activity:

// assuming you are using a LinearLayoutManager: 
final int firstVisibleIndex = mLinearLayoutManager.findFirstVisibleItemPosition(); 
final int lastVisibleIndex = mLinearLayoutManager.findLastVisibleItemPosition(); 

for (int i = firstVisibleIndex; i <= lastVisibleIndex; i++) { 
    YourViewHolder viewHolder = (YourViewHolder) findViewHolderForAdapterPosition (i); 
    viewHolder.stopRepeatingTask(); 
} 

I podobnie, można ponownie uruchomić zadania w onResume swojej Activity.

ALE: Teraz, gdy to pisałem nie jestem pewien, czy może istnieć ViewHolder s poza widzialnym obszarze RecyclerView (czyli przed pierwszym lub po ostatniej widocznej pozycji), które są już związane, ale to nie będzie zostać osiągnięty tą metodą. Jeśli okaże się, że tak jest, możesz nadal przeglądać wszystkie indeksy elementów w adapterze i odrzucić wszystkie zwracane wartości.

+0

znalazłem rozwiązanie samemu, poprawiłem twoją sugestię, rozwiązałem część problemu. Utwórz nazwę CompositeSubscription w adapterze, dodaj subskrypcję do niej w metodzie reapeatingTaskMethod, onActivityPause call.removeSubscriptions, w której wyczyścisz adapter compositeSubscriptionObject. Rozpoczęcie zadania nie ma znaczenia, ponieważ po wznowieniu działania każdy widok zostanie przerysowany, więc wszystkie zegary będą ponownie uruchamiane –

+0

, które działa, ponieważ zegar jest w rzeczywistości czasem odstąpienia od rzeczywistego timera –

+0

, ale twoja odpowiedź również działa, więc przyjmuję to –

Powiązane problemy