5

Ho una configurazione di ViewPager che sta disegnando i dati per le sue pagine (viste) dai dati passati da un server. A volte, il server invierà nuovi dati che riorganizzeranno le visualizzazioni (e talvolta aggiungeranno nuove viste) e ho bisogno di farlo accadere senza problemi sul mio dispositivo Android mentre l'utente sta attualmente visualizzando un particolare frammento.aggiornamento viewpager con frammenti in un nuovo ordine

Ho impostato per chiamare notifyDataSetChanged() quando i nuovi dati vengono estratti dal server, ma sembra mantenere una versione memorizzata nella cache delle diapositive a sinistra ea destra della diapositiva attualmente visualizzata che potenzialmente cambierà con il riordino Ho esaminato questo argomento qui: ViewPager PagerAdapter not updating the View e implementato la prima soluzione che funziona bene, oltre a ricaricare la diapositiva corrente che viene visualizzata che non funzionerà per i miei scopi. Ho preso uno sguardo superficiale nell'implementare il metodo setTag() proposto su quella stessa pagina nella seconda risposta e che avrebbe funzionato per aggiornare le informazioni sulle diapositive, ma non mi aiuterebbe a riordinarle.

c'è un modo per riordinare tutte le diapositive dietro le quinte senza provocare alcun rutto nella diapositiva attualmente visualizzata?

TIA

EDIT: l'aggiunta di codice e di chiedere ulteriori chiarimenti

Questa è la mia classe di adattatori.

private class ScreenSlidePagerAdapter extends FragmentPagerAdapter { 
    ContestEntriesModel entries; 

    public ScreenSlidePagerAdapter(FragmentManager fm, ContestEntriesModel Entries) { 
     super(fm); 
     this.entries = Entries; 
    } 

    @Override 
    public long getItemId(int position) { 
     return entries.entries[position].ContestEntryId; 

    } 

    @Override 
    public int getItemPosition(Object object) { 
     android.support.v4.app.Fragment f = (android.support.v4.app.Fragment)object; 
     for(int i = 0; i < getCount(); i++){ 

      android.support.v4.app.Fragment fragment = getItem(i); 
      if(f.equals(fragment)){ 
       return i; 
      } 
     } 
     return POSITION_NONE; 
    } 


    @Override 
    public android.support.v4.app.Fragment getItem(int position) { 

     long entryId = getItemId(position); 
     //Log.d("EntryIds",Integer.toString(entryId)); 
     if(mItems.get(entryId) != null) { 
      return mItems.get(entryId); 
     } 
     Fragment f = ScreenSlidePageFragment.create(position); 
     mItems.put(entryId, f); 
     return f; 
    } 

    @Override 
    public int getCount() { 
     return NUM_PAGES; 
    } 
} 

E qui è quello che sto usando in caso di nuove payload scende dal server:

@Override 
    protected void onPostExecute(ContestEntriesModel entries) { 
     Fragment currentFragment = ContestEntries.mItems.get(ContestEntries.CurrentEntryId); 
     Log.d("fromUpdate",Long.toString(ContestEntries.CurrentEntryId)); 
     ContestEntries.Entries = entries; 
     ContestEntries.NUM_PAGES = ContestEntries.Entries.entries.length; 
     ContestEntries.mPagerAdapter.notifyDataSetChanged(); 
     ContestEntries.mPager.setCurrentItem(ContestEntries.mPagerAdapter.getItemPosition(currentFragment)); 
    } 
+0

Chiamare 'getItem (int)' nella tua implementazione creerà un nuovo frammento ogni volta, perché non hai implementato alcuna forma di memorizzazione nella cache. Ogni volta che crei un nuovo frammento, 'getItemPosition (Object)' restituirà sempre 'POSITION_NONE', motivo per cui ricarica la diapositiva corrente su cui ti trovi. – Reinier

+0

ok, puoi indicarmi una risorsa in cui potrei imparare come implementare una qualche forma di memorizzazione nella cache? Inoltre, l'oggetto frammento che sto usando non ha un metodo newInstance() ... –

+0

Spiegazione: senza la cache dal mio esempio, il frammento passato come 'Object' non sarà mai uguale al valore restituito da' getItem (int) ', perché i riferimenti all'oggetto non sono gli stessi. Mentre è possibile superare questo problema implementando un metodo 'equals()' nel frammento, ciò significherebbe che si sta creando un nuovo frammento con ogni chiamata a 'getItem (int)' - che è un inutile spreco di risorse. – Reinier

risposta

6

Controllare my answer here. La chiave è di ignorare sia getItemId(int) e getItemPosition(Object) nell'adattatore.

getItemId(int) viene utilizzato per identificare le pagine in modo univoco all'interno del set di dati. getItemPosition(Object) viene utilizzato per recuperare la posizione (aggiornata) per questa pagina univoca nel set di dati.

Se si desidera mantenere l'attenzione sulla stessa pagina prima e dopo l'aggiornamento (aggiunta/rimozione di pagine), è necessario chiamare viewpager.setCurrentItem(int) per la nuova posizione della pagina dopo aver chiamato .notifyDataSetChanged() sull'adattatore.

+0

questo sembra molto promettente. Devo ammettere che non sono uno sviluppatore Android e questo è uno dei miei primi veri progetti. Darò un suggerimento al tuo suggerimento, ma sii pronto a farmi altre domande sull'implementazione, se non ti dispiace. –

+0

Ok, ho corso la mia prima sfida. Il modo in cui sto facendo è passare il numero totale di "diapositive" dal mio server. Sto quindi riempiendo un array con dati che non sono direttamente collegati dal mio cercapersone (nessun vero "set di dati" di per sé) e in una classe di estensione Fragment, sto semplicemente riempiendo le mie diapositive in base all'indice di quell'array che è passato attraverso il mio mPageNumber. Quindi non penso di avere una "chiave" reale che posso usare nel tuo esempio getItemId() sulla tua pagina collegata. Posso postare del codice nel mio OP se pensi che sarebbe di aiuto. –

+0

Che tipo di articoli ricevi dal tuo server? Non contengono qualche forma di identificatore univoco? Altrimenti potresti costruire un identificatore, ad es. tagliando i singoli oggetti. Poiché 'getItemId (int)' è il modo in cui 'ViewPager' identifica le uniche voci di pagina, questa è la strada da percorrere quando si tratta di avere pagine con posizioni dinamiche. E sì - il codice di esempio potrebbe aiutare. – Reinier

Problemi correlati