12
votes

Afficher le bouton de retour sur la barre d'outils sur le premier écran du graphique de navigation

J'essaie le composant de navigation androidx et j'ai configuré mon activité avec une barre d'outils et un conteneur. Je fais cela dans l'un des écrans intermittents de mon application qui a beaucoup de navigation / étapes internes et j'ai pensé que je pourrais essayer le composant de navigation arch.

Puisqu'il s'agit d'un écran intermittent, je souhaite afficher un bouton de retour sur la barre d'outils à partir du premier écran lui-même.

J'ai déjà configuré la barre d'outils avec le code ci-dessous dans la méthode onCreate () de mon activité d'hôte,

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/navigation"
    app:startDestination="@id/listing">

    <fragment
        android:id="@+id/listing"
        android:name=".ui.ItemsListingFragment"
        android:label="Items"
        tools:layout="@layout/items_listing" >
        <action
            android:id="@+id/listToQuantity"
            app:destination="@id/quantity"
           />
        <action
            android:id="@+id/listToReason"
            app:destination="@id/reason"
            />
    </fragment>
    <fragment
        android:id="@+id/quantity"
        android:name=".ui.ItemQuanitySelectionFragment"
        android:label="Items"
        tools:layout="@layout/fragment_item_quanity_selection" >
        <action
            android:id="@+id/quantityToReason"
            app:destination="@id/reason"
            />
    </fragment>
    <fragment
        android:id="@+id/reason"
        android:name=".ui.ItemReasonFragment"
        android:label="Items"
        tools:layout="@layout/fragment_item_reason">
    </fragment>
</navigation>

Je peux voir le bouton retour / flèche arrière sur le deuxième écran de mon graphique mais pas sur le premier écran.

 setSupportActionBar(toolbar);
 if (getSupportActionBar() != null) {
   getSupportActionBar().setDisplayHomeAsUpEnabled(true);
   getSupportActionBar().setDisplayShowHomeEnabled(true);
 }
NavigationUI.setupActionBarWithNavController(this, navHostFragment.getNavController());

Quels autres changements dois-je apporter pour ajouter le bouton de retour sur la barre d'outils dès la première étape.


0 commentaires

4 Réponses :


20
votes

Comme vous l'avez noté, le composant de navigation affiche le bouton de retour sur toutes les destinations sauf le niveau supérieur. Il utilise un AppBarConfiguration pour déterminer quelles destinations sont considérées comme «de premier niveau».

Vous devez donc:
1) créer AppBarConfiguration sans destinations de premier niveau
2) appeler une version à 3 arguments de setupActionBarWithNavController

new AppBarConfiguration.Builder().setFallbackOnNavigateUpListener(listener).build()

Pour personnaliser le comportement du bouton vers le haut sur la destination de `` niveau supérieur '', vous pouvez définir le OnNavigateUpListener dans votre générateur de configuration de la barre d'applications:

AppBarConfiguration abc = new AppBarConfiguration.Builder().build();
NavigationUI.setupActionBarWithNavController(this, navHostFragment.getNavController(), abc)

Plus d'informations des sources:
cliquez sur le bouton vers le haut pour NavigationUI.navigateUp(NavController, AppBarConfiguration) qui à son tour appelle NavController.navigateUp() qui tente de faire apparaître le backstack. Comme il ne peut pas remonter la pile, il ne fait rien et renvoie false. Votre écouteur de secours sera appelé dans ce cas.


4 commentaires

yap, le bouton retour apparaît mais ne sait pas comment revenir en arrière


@rguerra Ajout d'informations à ce sujet


Merci pour votre bonne recherche -> très spécifique .. travaille avec moi après 8 heures de recherche


très bien expliqué. Merci



1
votes

Lors de l'appel de setUpActionBarWithNavCntroller vous devez remplacer la fonction onSupportNavigateUp , comme ceci:

override fun onSupportNavigateUp(): Boolean {
    return findNavController(R.id.navHostFragment).navigateUp() 
            || super.onSupportNavigateUp()
}


0 commentaires

0
votes

1- J'ai créé une interface pour afficher / masquer le bouton de l'activité de l'hôte de navigation.

    private fun setupBackPress() {
    requireActivity()
        .onBackPressedDispatcher
        .addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() { 
            }
        })
}

2- Voici comment l'activité implémente les méthodes d'interface pour afficher / masquer le bouton haut:

fun someFunction() { 
    showUpButtonListener.showUpButton()
}

3- Voici la méthode de l'activité lorsque vous appuyez sur le bouton haut. Si dans la destination de départ, implémentez onBackPressed ():

    override fun onAttach(context: Context) {
    super.onAttach(context)
    if(context is ShowUpButtonListener){
        showUpButtonListener = context
    }
}

4- Dans un fragment, créez une propriété d'écouteur de bouton d'affichage:

private lateinit var showUpButtonListener: ShowUpButtonListener

5- Attribuer une propriété à l'activité contextuelle:

    override fun onSupportNavigateUp(): Boolean {
    val navController = this.findNavController(R.id.nav_host)
    if(!navController.navigateUp()){ // When in start destination
        onBackPressed()
    }
    return navController.navigateUp()
}

6- Dans l'appel de fragment, masquer ou afficher le bouton de la propriété d'interface:

    override fun showUpButton() {
    val navController = this.findNavController(R.id.nav_host)
    val listener = AppBarConfiguration.OnNavigateUpListener { navController.navigateUp() }
    val abc = AppBarConfiguration.Builder().setFallbackOnNavigateUpListener(listener).build()
    NavigationUI.setupActionBarWithNavController(this, navController, abc)
}


override fun hideUpButton() {
    val navController = this.findNavController(R.id.nav_host)
    NavigationUI.setupActionBarWithNavController(this, navController)
}

7- Dans un fragment peut écouter chaque fois que le bouton retour (PAS le bouton haut) est enfoncé:

    interface ShowUpButtonListener {
    fun showUpButton()
    fun hideUpButton()
}


0 commentaires

0
votes

Le bouton de retour s'affiche comme la méthode onSupportNavigateUp() renvoie true . Vous devez remplacer la méthode onSupportNavigateUp() .

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //
        setSupportActionBar(mToolbar)
        mNavController = getNavController();
        mAppBarConfiguration = new AppBarConfiguration.Builder().build();
        NavigationUI.setupActionBarWithNavController(this, mNavController, mAppBarConfiguration);
    }


    @Override
    public boolean onSupportNavigateUp() {
        //
        if (!(mNavController.navigateUp() || super.onSupportNavigateUp())) {
            onBackPressed();
        }
        return true;
    }


0 commentaires