Po prostu stanąłem przed problemem w naszym projekcie.Główną przyczyną jest sposób działania FragmentPagerAdapter:
FragmentPagerAdapter po prostu odłącza Fragment, którego obecnie nie potrzebuje z Widoku, ale nie usuwa go z jego FragmentManager. Kiedy chce ponownie wyświetlić Fragment, sprawdza, czy FragmentManager nadal zawiera Fragment przy pomocy znacznika utworzonego z ID widoku ViewPagera i identyfikatora zwróconego przez wywołania getItemId (pozycja) adapterów. Jeśli znajdzie Fragment, po prostu planuje dołączenie Fragmentu do swojego Widoku w ramach transakcji aktualizacji FragmentManager. Tylko wtedy, gdy nie znajdzie Fragmentu w ten sposób, tworzy nowy za pomocą adaptera getItem (pozycja) call!
Problem z Fragmentem zawierającym ViewPager z FragmentPagerAdapter polega na tym, że zawartość FragmentManager nigdy nie jest czyszczona, gdy zawierający Fragment jest umieszczany na tylnym stosie. Jeśli Fragment zawierający powraca z tylnego stosu, tworzy nowy widok, ale FragmentManager nadal zawiera fragmenty dołączone do starego widoku, a dołączenie istniejącego fragmentu już nie działa.
Najprostszym sposobem na pozbycie się tego problemu jest uniknięcie zagnieżdżonych fragmentów. :)
Drugi najprostszy sposób to, jak już wspomniano w innych postach, używanie programu ChildFragmentManager dla FragmentPagerAdapter, ponieważ jest on prawidłowo aktualizowany podczas cyklu życia fragmentu kontenera.
Ponieważ istnieją projekty (jak mój obecny), w których obie opcje nie są możliwe, opublikowałem tutaj rozwiązanie, które działa z dowolnym FragmentManager, używając hashCode z podstrony jako element id fragmentu w tym pozycja. Dostaje się za cenę przechowywania wszystkich fragmentów dla wszystkich pozycji w adapterze.
public class MyPagerAdapter extends FragmentPagerAdapter {
private static int COUNT = ...;
private final FragmentManager fragmentManager;
private Fragment[] subFragments = new Fragment[COUNT];
private FragmentTransaction cleanupTransaction;
public MyPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
this.fragmentManager = fragmentManager;
}
@Override
public Fragment getItem(int position) {
return getSubFragmentAtPosition(position);
}
@Override
public int getCount() {
return COUNT;
}
@Override
public long getItemId(int position) {
return getSubFragmentAtPosition(position).hashCode();
}
//The next three methods are needed to remove fragments no longer used from the fragment manager
@Override
public void startUpdate(ViewGroup container) {
super.startUpdate(container);
cleanupTransaction = fragmentManager.beginTransaction();
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
cleanupTransaction.remove((Fragment) object);
}
@Override
public void finishUpdate(ViewGroup container) {
super.finishUpdate(container);
cleanupTransaction.commit();
}
private Fragment getSubFragmentAtPosition(int position){
if (subFragments[position] == null){
subFragments[position] = ...;
}
return subFragments[position];
}
}
Ewentualny duplikat [Fragment w ViewPager przy użyciu FragmentPagerAdapter jest pusty przy drugim wyświetleniu] (http://stackoverflow.com/questions/7746652/fragment-in-viewpager-using-fragmentpageradapter-is-blank-the- drugi raz-to-jest) – blahdiblah