Avec Android 4.2, la bibliothèque de support technique a eu le support des fragments imbriqués voir ici . Je me suis amusée avec elle et ai découvert un comportement/bug intéressant concernant la pile arrière et - getChildFragmentManager () . Lorsque vous utilisez getChildFragmentManager () et addToBackStack (nom de chaîne), le système ne permet pas de retourner à la pile précédente jusqu'au fragment précédent. En revanche, lorsque vous utilisez - getFragmentManager () et addToBackStack (nom de chaîne), en appuyant sur le bouton Précédent, le système retourne au fragment précédent.
Pour moi, ce comportement est inattendu. En appuyant sur le bouton Précédent de mon appareil, je m'attends à ce que le dernier fragment ajouté à la pile arrière apparaisse, même si le fragment a été ajouté à la pile arrière dans le gestionnaire de fragments pour enfants.
Ce comportement est-il correct? Ce comportement est-il un bug? Y a-t-il un moyen de contourner ce problème?
public class FragmentceptionActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
final FrameLayout wrapper1 = new FrameLayout(this);
wrapper1.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper1.setId(1);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 0;
final TextView text = new TextView(this);
text.setLayoutParams(params);
text.setText("fragment 1");
wrapper1.addView(text);
setContentView(wrapper1);
getSupportFragmentManager().beginTransaction().addToBackStack(null)
.add(1, new Fragment1()).commit();
}
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout wrapper2 = new FrameLayout(getActivity());
wrapper2.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper2.setId(2);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 100;
final TextView text = new TextView(getActivity());
text.setLayoutParams(params);
text.setText("fragment 2");
wrapper2.addView(text);
return wrapper2;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getFragmentManager().beginTransaction().addToBackStack(null)
.add(2, new Fragment2()).commit();
}
}
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout wrapper3 = new FrameLayout(getActivity());
wrapper3.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper3.setId(3);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 200;
final TextView text = new TextView(getActivity());
text.setLayoutParams(params);
text.setText("fragment 3");
wrapper3.addView(text);
return wrapper3;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getChildFragmentManager().beginTransaction().addToBackStack(null)
.add(3, new Fragment3()).commit();
}
}
public class Fragment3 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout wrapper4 = new FrameLayout(getActivity());
wrapper4.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper4.setId(4);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 300;
final TextView text = new TextView(getActivity());
text.setLayoutParams(params);
text.setText("fragment 4");
wrapper4.addView(text);
return wrapper4;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getChildFragmentManager().beginTransaction().addToBackStack(null)
.add(4, new Fragment4()).commit();
}
}
public class Fragment4 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout wrapper5 = new FrameLayout(getActivity());
wrapper5.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper5.setId(5);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 400;
final TextView text = new TextView(getActivity());
text.setLayoutParams(params);
text.setText("fragment 5");
wrapper5.addView(text);
return wrapper5;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
}
public class FragmentceptionActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
final FrameLayout wrapper1 = new FrameLayout(this);
wrapper1.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper1.setId(1);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 0;
final TextView text = new TextView(this);
text.setLayoutParams(params);
text.setText("fragment 1");
wrapper1.addView(text);
setContentView(wrapper1);
getSupportFragmentManager().beginTransaction().addToBackStack(null)
.add(1, new Fragment1()).commit();
}
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout wrapper2 = new FrameLayout(getActivity());
wrapper2.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper2.setId(2);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 100;
final TextView text = new TextView(getActivity());
text.setLayoutParams(params);
text.setText("fragment 2");
wrapper2.addView(text);
return wrapper2;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getFragmentManager().beginTransaction().addToBackStack(null)
.add(2, new Fragment2()).commit();
}
}
public class Fragment2 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout wrapper3 = new FrameLayout(getActivity());
wrapper3.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper3.setId(3);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 200;
final TextView text = new TextView(getActivity());
text.setLayoutParams(params);
text.setText("fragment 3");
wrapper3.addView(text);
return wrapper3;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getFragmentManager().beginTransaction().addToBackStack(null)
.add(3, new Fragment3()).commit();
}
}
public class Fragment3 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout wrapper4 = new FrameLayout(getActivity());
wrapper4.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper4.setId(4);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 300;
final TextView text = new TextView(getActivity());
text.setLayoutParams(params);
text.setText("fragment 4");
wrapper4.addView(text);
return wrapper4;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getFragmentManager().beginTransaction().addToBackStack(null)
.add(4, new Fragment4()).commit();
}
}
public class Fragment4 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final FrameLayout wrapper5 = new FrameLayout(getActivity());
wrapper5.setLayoutParams(new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
wrapper5.setId(5);
final FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.topMargin = 400;
final TextView text = new TextView(getActivity());
text.setLayoutParams(params);
text.setText("fragment 5");
wrapper5.addView(text);
return wrapper5;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
}
On dirait un bug. Consultez: http://code.google.com/p/Android/issues/detail?id=4032
Pour une solution de contournement que j'ai utilisée avec succès (comme suggéré dans les commentaires):
@Override
public void onBackPressed() {
// If the fragment exists and has some back-stack entry
if (mActivityDirectFragment != null && mActivityDirectFragment.getChildFragmentManager().getBackStackEntryCount() > 0){
// Get the fragment fragment manager - and pop the backstack
mActivityDirectFragment.getChildFragmentManager().popBackStack();
}
// Else, nothing in the direct fragment back stack
else{
// Let super handle the back press
super.onBackPressed();
}
}
Cette solution est peut-être la meilleure version de la réponse @Sean:
@Override
public void onBackPressed() {
// if there is a fragment and the back stack of this fragment is not empty,
// then emulate 'onBackPressed' behaviour, because in default, it is not working
FragmentManager fm = getSupportFragmentManager();
for (Fragment frag : fm.getFragments()) {
if (frag.isVisible()) {
FragmentManager childFm = frag.getChildFragmentManager();
if (childFm.getBackStackEntryCount() > 0) {
childFm.popBackStack();
return;
}
}
}
super.onBackPressed();
}
Encore une fois, j'ai préparé cette solution sur la base de la réponse @Sean ci-dessus.
Comme @ AZ13 l'a dit, cette solution n'est réalisable que dans des situations de fragment enfant à un niveau. Dans le cas de fragments à plusieurs niveaux, les travaux deviennent un peu complexes, je vous recommande donc d’essayer cette solution uniquement dans le cas réalisable que j’ai dit. =)
Note: Puisque la méthode getFragments
est maintenant une méthode privée, cette solution ne fonctionnera pas. Vous pouvez consulter les commentaires pour trouver un lien suggérant une solution à ce problème.
Cette solution est peut-être la meilleure version de la réponse de @ismailarilik:
Version imbriquée de fragment
private boolean onBackPressed(FragmentManager fm) {
if (fm != null) {
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
return true;
}
List<Fragment> fragList = fm.getFragments();
if (fragList != null && fragList.size() > 0) {
for (Fragment frag : fragList) {
if (frag == null) {
continue;
}
if (frag.isVisible()) {
if (onBackPressed(frag.getChildFragmentManager())) {
return true;
}
}
}
}
}
return false;
}
@Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (onBackPressed(fm)) {
return;
}
super.onBackPressed();
}
La vraie réponse à cette question se trouve dans la fonction de la transaction de fragment appelée setPrimaryNavigationFragment.
/**
* Set a currently active fragment in this FragmentManager as the primary navigation fragment.
*
* <p>The primary navigation fragment's
* {@link Fragment#getChildFragmentManager() child FragmentManager} will be called first
* to process delegated navigation actions such as {@link FragmentManager#popBackStack()}
* if no ID or transaction name is provided to pop to. Navigation operations outside of the
* fragment system may choose to delegate those actions to the primary navigation fragment
* as returned by {@link FragmentManager#getPrimaryNavigationFragment()}.</p>
*
* <p>The fragment provided must currently be added to the FragmentManager to be set as
* a primary navigation fragment, or previously added as part of this transaction.</p>
*
* @param fragment the fragment to set as the primary navigation fragment
* @return the same FragmentTransaction instance
*/
public abstract FragmentTransaction setPrimaryNavigationFragment(Fragment fragment);
Vous devez définir cette fonction sur le fragment parent initial lorsque l'activité l'ajoute. J'ai une fonction replaceFragment dans mon activité qui ressemble à ceci:
public void replaceFragment(int containerId, BaseFragment fragment, boolean addToBackstack) {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setPrimaryNavigationFragment(fragment);
if (addToBackstack) {
fragmentTransaction.addToBackStack(fragment.TAG);
}
fragmentTransaction.replace(containerId, fragment).commit();
}
Cela vous donne le même comportement que si vous reveniez du fragment B normal au fragment A, sauf qu'il se trouve également sur les fragments enfants!
Avec cette réponse, il gérera la vérification arrière récursive et donnera à chaque fragment la possibilité de remplacer le comportement par défaut. Cela signifie que vous pouvez faire en sorte qu'un fragment hébergeant un ViewPager fasse quelque chose de spécial, comme par exemple faire défiler la page vers l'arrière-plan ou vers la page d'accueil, puis à la sortie suivante.
Ajoutez ceci à votre activité qui étend AppCompatActivity.
@Override
public void onBackPressed()
{
if(!BaseFragment.handleBackPressed(getSupportFragmentManager())){
super.onBackPressed();
}
}
Ajoutez ceci à votre BaseFragment ou à la classe dont vous pouvez hériter tous vos fragments.
public static boolean handleBackPressed(FragmentManager fm)
{
if(fm.getFragments() != null){
for(Fragment frag : fm.getFragments()){
if(frag != null && frag.isVisible() && frag instanceof BaseFragment){
if(((BaseFragment)frag).onBackPressed()){
return true;
}
}
}
}
return false;
}
protected boolean onBackPressed()
{
FragmentManager fm = getChildFragmentManager();
if(handleBackPressed(fm)){
return true;
}
else if(getUserVisibleHint() && fm.getBackStackEntryCount() > 0){
fm.popBackStack();
return true;
}
return false;
}
Ce code va parcourir l'arborescence des gestionnaires de fragments et renvoyer le dernier qui a été ajouté et qui contient tous les fragments qu'il peut extraire de la pile:
private FragmentManager getLastFragmentManagerWithBack(FragmentManager fm)
{
FragmentManager fmLast = fm;
List<Fragment> fragments = fm.getFragments();
for (Fragment f : fragments)
{
if ((f.getChildFragmentManager() != null) && (f.getChildFragmentManager().getBackStackEntryCount() > 0))
{
fmLast = f.getFragmentManager();
FragmentManager fmChild = getLastFragmentManagerWithBack(f.getChildFragmentManager());
if (fmChild != fmLast)
fmLast = fmChild;
}
}
return fmLast;
}
Appelez la méthode:
@Override
public void onBackPressed()
{
FragmentManager fm = getLastFragmentManagerWithBack(getSupportFragmentManager());
if (fm.getBackStackEntryCount() > 0)
{
fm.popBackStack();
return;
}
super.onBackPressed();
}
La raison en est que votre activité provient de FragmentActivity, qui gère l’appui sur la touche RETOUR (voir la ligne 173 de FragmentActivity .
Dans notre application, j'utilise un ViewPager (avec des fragments) et chaque fragment peut avoir des fragments imbriqués. La façon dont j'ai géré cela est par:
void onBackKeyPressed()
Notez également que j'utilise getChildFragmentManager()
dans les fragments pour imbriquer correctement les fragments. Vous pouvez voir une discussion et une explication dans ce post pour les développeurs Android .
Merci à tous pour leur aide, cette version (modifiée) fonctionne pour moi:
@Override
public void onBackPressed() {
if (!recursivePopBackStack(getSupportFragmentManager())) {
super.onBackPressed();
}
}
/**
* Recursively look through nested fragments for a backstack entry to pop
* @return: true if a pop was performed
*/
public static boolean recursivePopBackStack(FragmentManager fragmentManager) {
if (fragmentManager.getFragments() != null) {
for (Fragment fragment : fragmentManager.getFragments()) {
if (fragment != null && fragment.isVisible()) {
boolean popped = recursivePopBackStack(fragment.getChildFragmentManager());
if (popped) {
return true;
}
}
}
}
if (fragmentManager.getBackStackEntryCount() > 0) {
fragmentManager.popBackStack();
return true;
}
return false;
}
REMARQUE: vous souhaiterez probablement également définir la couleur d'arrière-plan de ces fragments imbriqués sur la couleur d'arrière-plan de la fenêtre du thème de l'application, car ils sont par défaut transparents. Un peu en dehors du champ de cette question, mais cela est accompli en résolvant l'attribut Android.R.attr.windowBackground et en définissant l'arrière-plan de la vue Fragment sur cet ID de ressource.
Cette solution peut être meilleure, car elle vérifie tous les niveaux de fragments imbriqués:
/**
* This method will go check all the back stacks of the added fragments and their nested fragments
* to the the {@code FragmentManager} passed as parameter.
* If there is a fragment and the back stack of this fragment is not empty,
* then emulate 'onBackPressed' behaviour, because in default, it is not working.
*
* @param fm the fragment manager to which we will try to dispatch the back pressed event.
* @return {@code true} if the onBackPressed event was consumed by a child fragment, otherwise {@code false}.
*/
public static boolean dispatchOnBackPressedToFragments(FragmentManager fm) {
List<Fragment> fragments = fm.getFragments();
boolean result;
if (fragments != null && !fragments.isEmpty()) {
for (Fragment frag : fragments) {
if (frag != null && frag.isAdded() && frag.getChildFragmentManager() != null) {
// go to the next level of child fragments.
result = dispatchOnBackPressedToFragments(frag.getChildFragmentManager());
if (result) return true;
}
}
}
// if the back stack is not empty then we pop the last transaction.
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
fm.executePendingTransactions();
return true;
}
return false;
}
dans votre activité onBackPressed
vous pouvez simplement l'appeler ainsi:
FragmentManager fm = getSupportFragmentManager();
// if there is a fragment and the back stack of this fragment is not empty,
// then emulate 'onBackPressed' behaviour, because in default, it is not working
if (!dispatchOnBackPressedToFragments(fm)) {
// if no child fragment consumed the onBackPressed event,
// we execute the default behaviour.
super.onBackPressed();
}
Plus de 5 ans et cette question est toujours d'actualité. Si vous ne souhaitez pas utiliser fragmentManager.getFragments () en raison de sa restriction. Étendre et utiliser les classes ci-dessous:
NestedFragmentActivity.Java
abstract public class NestedFragmentActivity extends AppCompatActivity {
private final Stack<Integer> mActiveFragmentIdStack = new Stack<>();
private final Stack<String> mActiveFragmentTagStack = new Stack<>();
@Override
public void onBackPressed() {
if (mActiveFragmentIdStack.size() > 0 && mActiveFragmentTagStack.size() > 0) {
// Find by id
int lastFragmentId = mActiveFragmentIdStack.lastElement();
NestedFragment nestedFragment = (NestedFragment) getSupportFragmentManager().findFragmentById(lastFragmentId);
// If cannot find by id, find by tag
if (nestedFragment == null) {
String lastFragmentTag = mActiveFragmentTagStack.lastElement();
nestedFragment = (NestedFragment) getSupportFragmentManager().findFragmentByTag(lastFragmentTag);
}
if (nestedFragment != null) {
nestedFragment.onBackPressed();
}
// If cannot find by tag, then simply pop
mActiveFragmentTagStack.pop();
mActiveFragmentIdStack.pop();
} else {
super.onBackPressed();
}
}
public void addToBackStack(int fragmentId, String fragmentTag) {
mActiveFragmentIdStack.add(fragmentId);
mActiveFragmentTagStack.add(fragmentTag);
}
}
NestedFragment.Java
abstract public class NestedFragment extends Fragment {
private final Stack<Integer> mActiveFragmentIdStack = new Stack<>();
private final Stack<String> mActiveFragmentTagStack = new Stack<>();
private NestedFragmentActivity mParentActivity;
private NestedFragment mParentFragment;
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (getParentFragment() == null) {
try {
mParentActivity = (NestedFragmentActivity) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement " + NestedFragmentActivity.class.getName());
}
} else {
try {
mParentFragment = (NestedFragment) getParentFragment();
} catch (ClassCastException e) {
throw new ClassCastException(getParentFragment().getClass().toString()
+ " must implement " + NestedFragment.class.getName());
}
}
}
public void onBackPressed() {
if (mActiveFragmentIdStack.size() > 0 && mActiveFragmentTagStack.size() > 0) {
// Find by id
int lastFragmentId = mActiveFragmentIdStack.lastElement();
NestedFragment nestedFragment = (NestedFragment) getChildFragmentManager().findFragmentById(lastFragmentId);
// If cannot find by id, find by tag
if (nestedFragment == null) {
String lastFragmentTag = mActiveFragmentTagStack.lastElement();
nestedFragment = (NestedFragment) getChildFragmentManager().findFragmentByTag(lastFragmentTag);
}
if (nestedFragment != null) {
nestedFragment.onBackPressed();
}
// If cannot find by tag, then simply pop
mActiveFragmentIdStack.pop();
mActiveFragmentTagStack.pop();
} else {
getChildFragmentManager().popBackStack();
}
}
private void addToBackStack(int fragmentId, String fragmentTag) {
mActiveFragmentIdStack.add(fragmentId);
mActiveFragmentTagStack.add(fragmentTag);
}
public void addToParentBackStack() {
if (mParentFragment != null) {
mParentFragment.addToBackStack(getId(), getTag());
} else if (mParentActivity != null) {
mParentActivity.addToBackStack(getId(), getTag());
}
}
}
Explication:
Chaque activité et fragment étendu des classes ci-dessus gère sa propre pile d'arrière-plan pour chacun de ses enfants, et pour les enfants des enfants, etc. Le backstack est simplement un enregistrement de tags/ids "fragment actif". La mise en garde est donc de toujours fournir une balise et/ou un identifiant pour votre fragment.
Lors de l'ajout au backstack d'un childFragmentManager, vous devez également appeler "addToParentBackStack ()". Cela garantit que le tag/id du fragment est ajouté au fragment/activité parent pour les pops ultérieurs.
Exemple:
getChildFragmentManager().beginTransaction().replace(
R.id.fragment,
fragment,
fragment.getTag()
).addToBackStack(null).commit();
addToParentBackStack();
j'ai pu gérer le fragment de pile arrière en ajoutant au fragment parent cette méthode à la méthode onCreate View () et en passant à la vue racine.
private void catchBackEvent(View v){
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener( new OnKeyListener()
{
@Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
if(isEnableFragmentBackStack()){
getChildFragmentManager().popBackStack();
setEnableFragmentBackStack(false);
return true;
}
else
return false;
}
return false;
}
} );
}
La méthode estEnableFragmentBackStack () est un drapeau booléen pour savoir quand je suis sur le fragment principal ou sur le prochain.
Assurez-vous que lorsque vous validez le fragment devant disposer d’une pile, vous devez ajouter la méthode addToBackstack.