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);
}
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.
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();
}
}
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é
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.
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);
}
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
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.
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
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) :-) ;-)
Vous pouvez utiliser getFragmentManager().popBackStack()
dans Fragment
de base pour revenir en arrière.
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.
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;
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.
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.