2015-07-08 16 views
6

Così poche settimane fa ho posto questa domanda: recyclerview periodic ui child updates.Utilizzo di RxJava nell'adattatore RecyclerView

E oggi voglio refactoring quella funzionalità utilizzando Rxjava. In realtà è piuttosto semplice, realizzo il seguente modo:

@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(); 
     } 
    } 

Il problema tuttavia è diverso. Ho un navigationDrawer implementato con le attività che sono in pausa e non distrutto quando commutato. Quindi, dopo che passo all'attività che non contiene questo adattatore, l'osservabile continua a inviare roba perché è un intervallo periodico osservabile. Quindi la mia domanda è: cosa dovrei fare? Ho bisogno di disiscriverti quando l'attività è in pausa, ma non ho idea di come da allora, e anche come iscriversi indietro. Qualche aiuto o idee?

+0

o dovrei semplicemente controllare su Next e non fare nulla se l'attività è in pausa? –

risposta

1

Quindi, se ho capito bene, un modo per risolvere il problema è quello di rispondere alla domanda: In un Activity che contiene un RecyclerView, come faccio a riferimenti a tutti i ViewHolder s che sono attualmente visualizzato/legavano?

Ad esempio, per fermare tutti gli aggiornamenti si potrebbe poi fare quanto segue nella onPause() del vostro 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(); 
} 

E allo stesso modo, è possibile riavviare i compiti nel onResume del vostro Activity.

MA: Ora che ho scritto questo io non sono sicuro se ci possono essere ViewHolder s oltre l'area visibile del RecyclerView (vale a dire prima della prima o dopo l'ultima voce visibile) che sono già legati, ma che non sarebbe essere raggiunto con questo metodo. Se ciò si verifica, puoi ancora scorrere tutti gli indici degli articoli nell'adattatore e scartare i valori di ritorno null.

+0

ho trovato la soluzione da solo, anche se il tuo suggerimento risolve parte del problema. Creare una sottoscrizione composita nell'adattatore, aggiungere la sottoscrizione ad esso nel reapeatingTaskMethod, onActivityPause chiama adapter.removeSubscriptions in cui si deseleziona l'adattatore compositeSubscriptionObject. L'avvio dell'attività non ha importanza perché una volta riavviata l'attività, ogni vista verrà ridisegnata in modo che tutti i timer si avvieranno di nuovo –

+0

che funziona perché il timer è in realtà un timeStamp non un vero timer –

+0

ma la risposta funziona allo stesso modo, quindi lo accetterò –