Mam konfigurację ViewPager, która pobiera dane dla swoich stron (widoków) z danych przekazywanych z serwera. Czasami serwer wysyła nowe dane, które zmieniają kolejność wyświetleń (a czasami dodają nowe widoki) i muszę sprawić, że stanie się to bezproblemowo na moim urządzeniu z Androidem, podczas gdy użytkownik aktualnie ogląda określony fragment.aktualizowanie podglądu stron z fragmentami w nowej kolejności
Mam ustawić wywołanie notifyDataSetChanged(), gdy nowe dane są pobierane z serwera, ale wydaje się, że przechowują buforowaną wersję slajdów po lewej i prawej stronie aktualnie wyświetlanego slajdu, które potencjalnie ulegnie zmianie z kolejność. Przyjrzałem się temu tematowi: ViewPager PagerAdapter not updating the View i zaimplementowałem pierwsze rozwiązanie, które działa dobrze, inne niż ładuje bieżący slajd, który jest oglądany, co nie zadziała w moich celach. Wziąłem płytko-nurkowe spojrzenie na implementację metody setTag() zaproponowanej na tej samej stronie w drugiej odpowiedzi, która działałaby na rzecz aktualizacji informacji na slajdach, ale nie pomoże mi to w zmianie kolejności.
Czy jest jakiś sposób, że mogę zmienić kolejność wszystkich slajdów za kulisami bez powodowania jakichkolwiek zniekształceń w aktualnie wyświetlanym slajdzie?
TIA
EDIT: dodanie kodu i prosząc o jakiś dalszych wyjaśnień
To moja klasa adaptera.
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;
}
}
A oto co używam, gdy nowy ładunek zstępuje z serwera:
@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));
}
Wywołanie 'getItem (int)' w twojej implementacji spowoduje utworzenie nowego Fragmentu za każdym razem, ponieważ nie zaimplementowałeś jakiejś formy buforowania. Podczas tworzenia nowego fragmentu za każdym razem, 'getItemPosition (Object)' zawsze zwraca 'POSITION_NONE', dlatego też ładuje bieżący slajd, na którym się znajdujesz. – Reinier
ok, czy możesz wskazać mi źródło, w którym mogę się dowiedzieć, jak zaimplementować jakąś formę buforowania? Ponadto obiekt fragmentu, którego używam, nie ma metody newInstance() ... –
Objaśnienie: bez buforowania z mojego przykładu Fragment przekazany jako 'Object' nigdy nie będzie równa wartości zwracanej przez' getItem (int) ', ponieważ odwołania do obiektów nie są takie same. Chociaż możesz to przezwyciężyć, wprowadzając metodę 'equals()' w swoim Fragmentie, to nadal znaczyłoby, że tworzysz nowy Fragment z każdym wywołaniem 'getItem (int)' - co jest bezużytecznym marnowaniem zasobów. – Reinier