web-dev-qa-db-fra.com

Fragment appuyant sur le bouton arrière

J'ai maintenant une activité contenant des fragments 

[1], [2], [3], [4] 

Si vous appuyez sur les boutons, [3], vous pouvez le rediriger vers [4].

Je voudrais implémenter le bouton de retour comme indiqué ci-dessous.

en appuyant à nouveau sur [4], il retourne à [3]

en appuyant à nouveau sur [3], il retourne à [2]

lorsque vous appuyez de nouveau sur [1], l'activité se termine ();

En ce qui concerne l'implémentation actuelle, l'activité est terminée au lieu d'afficher le fragment. Pourriez-vous s'il vous plaît me dire ce que je devrais faire ou garder à l'esprit? 

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    if( keyCode==KeyEvent.KEYCODE_BACK) 
    {   

        finish();
    }       

        return super.onKeyDown(keyCode, event); 

}   
37
Raju yourPepe

Ok les gars, j'ai finalement trouvé une bonne solution.

Dans votre activité onCreate () hébergeant vos fragments, ajoutez un auditeur de changement de pile, comme ceci:

    fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            List<Fragment> f = fragmentManager.getFragments();
            Fragment frag = f.get(0);
            currentFragment = frag.getClass().getSimpleName();
        }
    });

(L'ajout de mon fragmenManager est également déclaré global) Maintenant, chaque fois que vous modifiez un fragment, le fragment en cours String devient le nom du fragment en cours. Ensuite, dans les activités onBackPressed (), vous pouvez contrôler les actions de votre bouton Retour de la manière suivante:

    @Override
    public void onBackPressed() {

    switch (currentFragment) {
        case "FragmentOne":
            // your code here (Maybe dialog)
            return;
        case "FragmentTwo":
            // your code here
            return;
        default:
            fragmentManager.popBackStack();
            // default action for any other fragment (return to previous)
    }

}

Je peux confirmer que cette méthode fonctionne pour moi.

1
Haider Malik

Cela a fonctionné pour moi.

-Add .addToBackStack (null) lorsque vous appelez le nouveau fragment à partir d'activité.

    FragmentTransaction mFragmentTransaction = getFragmentManager()
                .beginTransaction();
    ....
    mFragmentTransaction.addToBackStack(null);

-Ajouter onBackPressed () à votre activité

    @Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() == 0) {
        this.finish();
    } else {
        getFragmentManager().popBackStack();
    }
}
87
Kamel

Le moyen le plus simple:

pour résumer() :

@Override
public void onResume() {
    super.onResume();

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                // handle back button's click listener
                Toast.makeText(getActivity(), "Back press", Toast.LENGTH_SHORT).show();
                return true;
            }
            return false;
        }
    });

}

Edit 1 : Si le fragment a EditText.

private EditText editText;

onCreateView () :

editText = (EditText) rootView.findViewById(R.id.editText);

pour résumer() :

@Override
public void onResume() {
    super.onResume();

    editText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                editText.clearFocus();
            }
            return false;
        }
    });

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                // handle back button's click listener
                Toast.makeText(getActivity(), "Back press", Toast.LENGTH_SHORT).show();
                return true;
            }
            return false;
        }
    });

}

Note: Cela fonctionnera si vous avez EditText dans fragment.

Terminé

48
Hiren Patel

Ceci est une solution de travail pour moi:

dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                    @Override
                    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                        if (keyCode == KeyEvent.KEYCODE_BACK) {
                            // DO WHAT YOU WANT ON BACK PRESSED
                            return true;
                        }
                        return false;
                    }
                });

Edition: Vous pouvez remplacer dialog par getView() pour les fragments.

8
savepopulation

Vous pouvez utiliser ceci .. Travaillé pour moi ..

Il semble que fragment [3] ne soit pas supprimé de la vue lorsque vous appuyez sur la touche Retour, vous devez donc le faire manuellement!

Tout d’abord, n’utilisez pas replace (), mais utilisez remove et add séparément. Il semble que replace () ne fonctionne pas correctement.

La partie suivante consiste à remplacer la méthode onKeyDown et à supprimer le fragment en cours chaque fois que le bouton Précédent est enfoncé.

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event)
 {
 if (keyCode == KeyEvent.KEYCODE_BACK)
 {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0)
    {
        this.finish();
        return false;
    }
    else
    {
        getSupportFragmentManager().popBackStack();
        removeCurrentFragment();

        return false;
    }



 }

  return super.onKeyDown(keyCode, event);
 }


public void removeCurrentFragment()
{
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

Fragment currentFrag =  getSupportFragmentManager().findFragmentById(R.id.f_id);
}
7
Piyush

Essayez cette solution simple: 

Dans votre activité, implémentez onBackPressed

 @Override
    public void onBackPressed() {
       if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
            getSupportFragmentManager().popBackStack();
        } else {
            finish();
        }
    }

Cela fonctionnera si vous voulez faire apparaître le fragment supérieur à chaque appui arrière . Remarque : - Lors de l'ajout d'un fragment à l'activité, ajoutez toujours la transaction dans la pile arrière pour que cela fonctionne

5
hitesh

Ce que je fais dans ce cas est d’implémenter la fonction onBackPressed () à partir de l’activité

@Override
public void onBackPressed() {
   super.onBackPressed();
   FragmentManager fm = getSupportFragmentManager();
   MyFragment myFragment = (MyFragment) fm.findFragmentById(R.id.my_fragment);

   if((myFragmen.isVisible()){
      //Do what you want to do
   }
}

Comment cela fonctionne pour vous aussi.

4
Jesus Almaral

Une solution encore meilleure pourrait consister à suivre un modèle de conception tel que l’événement de presse du bouton arrière soit propagé du fragment actif à l’activité hôte. Donc, c’est comme si… si l’un des fragments actifs consomme le back-press, l’Activité n’aurait pas le droit d’agir en conséquence, et inversement.

Une façon de le faire consiste à faire en sorte que tous vos fragments étendent un fragment de base doté d'une méthode abstraite 'boolean onBackPressed ()'.

@Override
public boolean onBackPressed() {
   if(some_condition)
      // Do something
      return true; //Back press consumed.
   } else {
      // Back-press not consumed. Let Activity handle it
      return false;
   }
}

Gardez une trace du fragment actif dans votre activité et dans son rappel onBackPressed, écrivez quelque chose comme ceci

@Override
public void onBackPressed() {
   if(!activeFragment.onBackPressed())
      super.onBackPressed();
   }
}

Ce post a ce modèle décrit en détail

4
Achin Kumar

Solution pour appuyer ou manipuler le bouton de retour dans Fragment.

La façon dont j'ai résolu mon problème, je suis sûr que cela vous aidera aussi:

1.Si vous n'avez pas de zone de texte d'édition dans votre fragment, vous pouvez utiliser le code ci-dessous

Ici MainHomeFragment est le fragment principal (quand j'appuie sur le bouton de retour du deuxième fragment, cela me prendra aussi MainHomeFragment)

    @Override
    public void onResume() {

    super.onResume();

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){

                MainHomeFragment mainHomeFragment = new SupplierHomeFragment();
                Android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getActivity().getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, mainHomeFragment);
                fragmentTransaction.commit();

                return true;    
            }    
            return false;
        }
    }); }

2.Si vous avez un autre fragment nommé Somefragment et qu'il a une zone de texte Editer, vous pouvez le faire de cette manière.

private EditText editText;

Puis dans,

onCreateView():    
editText = (EditText) view.findViewById(R.id.editText);

Puis substituez OnResume,

@Override
public void onResume() {
    super.onResume();

    editText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                editTextOFS.clearFocus();
                getView().requestFocus();
            }
            return false;
        }
    });

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){

                MainHomeFragment mainHomeFragment = new SupplierHomeFragment();
                Android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getActivity().getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, mainHomeFragment);
                fragmentTransaction.commit();

                return true;

            }

            return false;
        }
    });

}

C'est tout le monde (amitamie.com) :-) ;-)

3
Amit Kumar

Vous pouvez utiliser getFragmentManager().popBackStack() dans Fragment de base pour revenir en arrière.

3
Denny

Vous devez également vérifier l'événement Action_Down ou Action_UP. Si vous ne voulez pas vérifier alors onKey () Method appellera 2 fois.

getView().setFocusableInTouchMode(true);
getView().requestFocus();

getView().setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        Toast.makeText(getActivity(), "Back Pressed", Toast.LENGTH_SHORT).show();
                    return true;
                    }
                }
                return false;
            }
        });

Travaille très bien pour moi.

2
Tejas Mehta

si vous utilisez webview à l'intérieur d'un fragment, utilisez-le dans votre méthode onCreateView

webView.setOnKeyListener(new View.OnKeyListener(){

        @Override
        public boolean onKey(View view, int i, KeyEvent keyEvent) {
            if((i==KeyEvent.KEYCODE_BACK)&& webView.canGoBack()){
                webView.goBack();
                return true;
            }
            return false;
        }
    });

et importer cette classe

import Android.view.KeyEvent;
1
Akshansh Jain

Assurez-vous d'ajouter ce qui suit: 

if (event.getAction()!=KeyEvent.ACTION_DOWN)
                return true;

dans le bloc de code onKey pour éviter que l'événement n'appelle deux fois.

1
mossman252

j'utilise une méthode pour changer les fragments, il a donc le code suivant

 getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit).replace(R.id.content_frame, mContent, mContent.getClass().getSimpleName()).addToBackStack(null)
                .commit();

et pour le bouton de retour cela.

@Override
    public void onBackPressed() {
        // note: you can also use 'getSupportFragmentManager()'
        FragmentManager mgr = getSupportFragmentManager();
        if (mgr.getBackStackEntryCount() == 1) {
            // No backstack to pop, so calling super
            finish();
        } else {
            mgr.popBackStack();
        }
    }

la chose importante à noter est que j'utilise 1 pour vérifier getBackStackEntryCount car si vous ne l'utilisez pas et utilisez 0 utilisateur ne voit rien pour le dernier bouton de retour.

0
kamran hatami