web-dev-qa-db-fra.com

Comportement personnalisé de "remontée" pour certains fragments à l'aide du composant Navigation

Je veux ajouter une navigation ascendante personnalisée à partir d'un fragment à l'aide du composant Navigation

Dans ma build.gradle(app) j'utilise androidx.appcompat:appcompat:1.1.0-alpha04 dépendance pour avoir accès à onBackPressedDispatcher à partir de l'activité.

J'ai donc implémenté OnBackPressedCallback dans mon fragment et enregistré le rappel au répartiteur:

requireActivity().onBackPressedDispatcher.addCallback(this)

Je m'attendais à ce que le fait d'appuyer sur vers le haut dans la barre d'outils l'appelle, mais ce n'est pas le cas. Appuyez sur le bouton de retour de l'appareil pour l'appeler comme prévu.

Existe-t-il un moyen similaire d'ajouter un rappel en fragment lors de l'action de navigation vers le haut?

MISE À JOUR

méthodes remplacées onOptionsItemSelected et onSupportNavigateUp ne sont pas invoquées en appuyant sur le bouton haut dans la barre d'outils

16
Roko Spark

J'ai trouvé une solution

handleOnBackPressed() La méthode n'est invoquée que lorsque l'utilisateur clique sur le bouton Retour. Je me demande, pourquoi ni les méthodes onOptionsItemSelected() ni onSupportNavigateUp() n'ont pas été appelées en appuyant sur le "bouton haut" dans la barre d'outils. Et la réponse est que j'ai utilisé

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)

en activité pour configurer la barre d'outils avec le composant de navigation. Et cela a rendu la barre d'outils sensible au travail avec la navigation en interne, en appuyant sur le "bouton haut", vous n'avez invoqué aucune méthode remplacée dans l'activité ou des fragments.

Au lieu de cela devrait être utilisé

NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration)

Cela rendra actionBar sensible à la navigation, donc je peux utiliser les fonctions remplacées onOptionsItemSelected() et onSupportNavigateUp() Et le meilleur endroit (dans mon cas) pour ajouter un comportement personnalisé sur le "bouton haut" cliquez pour un certain écran est

onSupportNavigateUp()

d'activité hébergée, comme ça

override fun onSupportNavigateUp(): Boolean {
        val navController = this.findNavController(R.id.mainNavHostFragment)
        return when(navController.currentDestination?.id) {
            R.id.destinationOfInterest -> {
                // custom behavior here 
                true
            }
            else -> navController.navigateUp()
        }
}

Mais il vaut la peine de dire que si vous voulez implémenter un comportement personnalisé directement en fragment, la réponse de @Enzokie devrait fonctionner comme un charme

10
Roko Spark

Vous devez appeler onBackPressed() à partir de la propriété onBackPressedDispatcher. En supposant que votre barre d'outils est correctement configurée, vous pouvez utiliser le code ci-dessous dans votre activité.

override fun onOptionsItemSelected(menuItem : MenuItem?) : Boolean {
    if (menuItem.getItemId() == Android.R.id.home) {
        onBackPressedDispatcher.onBackPressed()
    }
    return super.onOptionsItemSelected(menuItem)
}

Ce que cela signifie:

Déclenchez un appel vers les rappels OnBackPressedCallback actuellement ajoutés dans l'ordre inverse dans lequel ils ont été ajoutés. Ce n'est que si le plus faux de sa OnBackPressedCallback#handleOnBackPressed() que tout rappel précédemment ajouté sera appelé.

J'utilise AndroidX dans mon exemple donc mon importation ressemblera

import androidx.appcompat.app.AppCompatActivity.

5
Enzokie

Cette configuration fonctionne également et vous n'aurez pas besoin de remplacer onSupportNavigateUp dans votre activité:

NavigationUI.setupWithNavController(toolbar, navController, appBarConfiguration)
toolbar.setNavigationOnClickListener {
    if (navController.currentDestination?.id == R.id.destinationOfInterest) {
        // Custom behavior here
    } else {
        NavigationUI.navigateUp(navController, configuration)
    }
}

Je préfère configurer le Toolbar car il gérera automatiquement la navigation vers le haut et ouvrira/fermera un DrawerLayout si vous en avez un.

0
Juan Cruz Soler