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