web-dev-qa-db-fra.com

Gestion du bouton de retour dans le composant de navigation Android

J'aimerais savoir comment gérer correctement l'action du bouton Précédent du système à l'aide du contrôleur de navigation. Dans mon application, j'ai deux fragments (par exemple, fragment1 et fragment2) et j'ai une action dans fragment1 avec destination to fragment2. Tout fonctionne bien sauf une chose - lorsque l'utilisateur appuie sur le bouton retour du système dans fragment2, je souhaite afficher une boîte de dialogue (à l'aide de DialogFragment par exemple) pour confirmer la sortie. Quel est le meilleur moyen d'implémenter ce comportement? Si j'utilise app:defaultNavHost="true" dans mon fragment d'hôte, il retourne automatiquement en ignorant mes règles. Et en plus, à quoi sert ce composant?

 enter image description here

Devrais-je utiliser "pop to" peut-être?

9
Kiryl Tkach

J'ai donc créé une interface

public interface OnBackPressedListener {
    void onBackPressed();
}

Et mis en œuvre par tous les fragments qui doivent gérer le bouton de retour. Dans l'activité principale, j'ai remplacé la méthode onBackPressed()

@Override
public void onBackPressed() {
    final Fragment currentFragment = mNavHostFragment.getChildFragmentManager().getFragments().get(0);
    final NavController controller = Navigation.findNavController(this, R.id.nav_Host_fragment);
    if (currentFragment instanceof OnBackPressedListener)
        ((OnBackPressedListener) currentFragment).onBackPressed();
    else if (!controller.popBackStack())
        finish();

}

Ainsi, si le fragment supérieur de mon hôte de navigation implémente l’interface OnBackPressedListener, j’appelle sa méthode onBackPressed(); ailleurs, j’ai simplement refait une pile et fermé l’application si la pile arrière est vide.

9
Kiryl Tkach

Voici une solution qui devrait faire ce que vous voulez, mais je pense que c'est une mauvaise solution, car elle va à l'encontre du principe du composant de navigation Android (laisser Android gérer la navigation).

Remplacez "onBackPressed" dans votre activité

override fun onBackPressed() {
    when(NavHostFragment.findNavController(nav_Host_fragment).currentDestination.id) {
        R.id.fragment2-> {
            val dialog=AlertDialog.Builder(this).setMessage("Hello").setPositiveButton("Ok", DialogInterface.OnClickListener { dialogInterface, i ->
                finish()
            }).show()
        }
        else -> {
            super.onBackPressed()
        }
    }
} 
3
Alex

Depuis this , il peut être implémenté en utilisant simplement JetPack implementation OnBackPressedCallback dans votre fragment .__ et l'ajouter à l'activité: getActivity().addOnBackPressedCallback(getViewLifecycleOwner(),this);

Votre fragment devrait ressembler à ceci:

public MyFragment extends Fragment implements OnBackPressedCallback {

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        getActivity().addOnBackPressedCallback(getViewLifecycleOwner(),this);
}

    @Override
    public boolean handleOnBackPressed() {
        //Do your job here
        //use next line if you just need navigate up
        //NavHostFragment.findNavController(this).navigateUp(); 
        //Log.e(getClass().getSimpleName(), "handleOnBackPressed");
        return true;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        getActivity().removeOnBackPressedCallback(this);
    }
}
2
Jurij Pitulja

Essaye ça. Je crois que ceci vous aidera.

remplacez fun onBackPressed () { when (mNavController.getCurrentDestination () !!. getId ()) {

    R.id.loginFragment -> {
        onWarningAlertDialog(this, "Alert", "Do you want to close this application ?")
    }
    R.id.registerFragment -> {
        super.onBackPressed()
    }
}

}

divertissement privé onWarningAlertDialog (mainActivity: MainActivity, s:

    val dialogBuilder = AlertDialog.Builder(this)
    dialogBuilder.setMessage(/*""*/s1)
            .setCancelable(false)
            .setPositiveButton("Proceed", DialogInterface.OnClickListener { dialog, id ->
                finish()
            })
            .setNegativeButton("Cancel", DialogInterface.OnClickListener { dialog, id ->
                dialog.cancel()
            })

    // create dialog box
    val alert = dialogBuilder.create()
    // set title for alert dialog box
    alert.setTitle("AlertDialogExample")
    // show alert dialog
    alert.show()
}
0
Anandharaj R