Un fragment n’est pas rattaché à son hébergeur ViewPager après son retour d’un autre fragment.
Une activité hébergeant un fragment dont la disposition contient un ViewPager ( PageListFragment
dans l’exemple ci-dessous). Le ViewPager est rempli par un FragmentStateViewPagerAdapter. Les fragments uniques hébergés dans le pageur ( PageFragment
dans l’exemple ci-dessous) peuvent ouvrir des listes de sous-pages contenant un nouvel ensemble de pages.
Tout fonctionne bien tant que le bouton retour n’est pas enfoncé. Dès que l’utilisateur ferme l’une des sous-listes, la liste précédente est recréée, mais sans la page affichée précédemment. Passer en revue les autres pages de la PageList parente fonctionne toujours.
Un exemple d’application peut être trouvé sur github :
public class MainActivity extends FragmentActivity { private static final Ssortingng CURRENT_FRAGMENT = MainActivity.class.getCanonicalName() + ".CURRENT_FRAGMENT"; public static final Ssortingng ARG_PARENTS = "Parents"; public void goInto(Ssortingng mHostingLevel, Ssortingng mPosition) { Fragment hostingFragment = newHostingFragment(mHostingLevel, mPosition); addFragment(hostingFragment); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); addBaseFragment(); } private void addBaseFragment() { Fragment hostingFragment = newHostingFragment("", ""); addFragment(hostingFragment); } private Fragment newHostingFragment(Ssortingng mHostingLevel, Ssortingng oldPosition) { Fragment hostingFragment = new PageListFragment(); Bundle args = new Bundle(); args.putSsortingng(ARG_PARENTS, mHostingLevel + oldPosition +" > "); hostingFragment.setArguments(args); return hostingFragment; } private void addFragment(Fragment hostingFragment) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragmentSpace, hostingFragment, CURRENT_FRAGMENT); transaction.addToBackStack(null); transaction.commit(); } }
public class PageListFragment extends Fragment { private Ssortingng mParentSsortingng; public PageListFragment() { // Required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_hosting, container, false); } @Override public void onResume() { mParentSsortingng = getArguments().getSsortingng(MainActivity.ARG_PARENTS); ViewPager viewPager = (ViewPager) getView().findViewById(R.id.viewPager); viewPager.setAdapter(new SimpleFragmentStatePagerAdapter(getFragmentManager(),mParentSsortingng)); super.onResume(); } private static class SimpleFragmentStatePagerAdapter extends FragmentStatePagerAdapter { private Ssortingng mHostingLevel; public SimpleFragmentStatePagerAdapter(FragmentManager fm, Ssortingng hostingLevel) { super(fm); this.mHostingLevel = hostingLevel; } @Override public android.support.v4.app.Fragment getItem(int position) { PageFragment pageFragment = new PageFragment(); Bundle args = new Bundle(); args.putSsortingng(MainActivity.ARG_PARENTS, mHostingLevel); args.putInt(PageFragment.ARG_POSITION, position); pageFragment.setArguments(args); return pageFragment; } @Override public int getCount() { return 5; } } }
public class PageFragment extends Fragment { public static final Ssortingng ARG_POSITION = "Position"; private Ssortingng mHostingLevel; private int mPosition; public PageFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View contentView = inflater.inflate(R.layout.fragment_page, container, false); setupTextView(contentView); setupButton(contentView); return contentView; } private void setupTextView(View contentView) { mPosition = getArguments().getInt(ARG_POSITION); mHostingLevel = getArguments().getSsortingng(MainActivity.ARG_PARENTS); TextView text = (TextView) contentView.findViewById(R.id.textView); text.setText("Parent Fragments " + mHostingLevel + " \n\nCurrent Fragment "+ mPosition); } private void setupButton(View contentView) { Button button = (Button) contentView.findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { openNewLevel(); } }); } protected void openNewLevel() { MainActivity activity = (MainActivity) getActivity(); activity.goInto(mHostingLevel, Integer.toSsortingng(mPosition)); } }
Après une longue enquête, le gestionnaire de fragment pose problème.
Lorsque vous utilisez une construction comme celle située au-dessus de la transaction de fragment pour rattacher le fragment à la liste de pages, celle-ci est supprimée silencieusement. C’est fondamentalement le même problème qui provoque une
java.lang.IllegalStateException: Recursive entry to executePendingTransactions
en essayant de modifier les fragments à l’intérieur du FragmentPager.
La même solution que pour les problèmes liés à cette erreur est également applicable ici. Lors de la construction de FragmentStatePagerAdapter, indiquez le gestionnaire de fragment enfant correct.
Au lieu de
viewPager.setAdapter(new SimpleFragmentStatePagerAdapter(getFragmentManager(),mParentSsortingng));
faire
viewPager.setAdapter(new SimpleFragmentStatePagerAdapter(getChildFragmentManager(),mParentSsortingng));
Voir aussi: github
Ce que Paul a omis de mentionner, c’est que si vous utilisez getChildFragmentManager , vous subirez alors le problème de «l’écran vide sur lequel vous avez appuyé».