web-dev-qa-db-fra.com

Ajout d'animations de transition personnalisées à la configuration de navigation inférieure avec la navigation Jetpack

Je travaille sur une application utilisant des composants Jetpack. J'ai cousu la navigation du bas avec trois fragments comme décrit dans le guide . Cependant, je ne peux pas comprendre comment changer l'animation de transition lors du basculement entre les fragments en appuyant sur le bouton de navigation correspondant.

Pour autant que je sache, il existe deux façons de créer des transitions:

  • Les passer en tant qu'options dans navigate(), qui n'est pas explicitement appelé dans ce cas;
  • Utiliser une action avec des attributs d'animation, mais je ne sais pas comment dire à la navigation d'utiliser ces actions. Peut-être que lui donner un identifiant spécifique fonctionnerait?

Alors, comment puis-je définir une animation de transition personnalisée sans avoir à renoncer à utiliser BottomNavigation.setupWithNavController(navController)

12
aksh1618

Je pense que vous pouvez obtenir ce comportement en créant des versions des fichiers d'animation R.anim.nav_default_ [Enter/Exit/PopEnter/PopExit] et en les plaçant dans votre répertoire de ressources anim. Le composant utilisera alors ces fichiers pour les animations par défaut. Il semble que cela ne devrait pas fonctionner comme ça, mais pour le moment.

1
Garry McKee

Je pense que vous ne pouvez pas, mais seriez intéressé par une solution.

Voici une solution de contournement, si cela aide:

Ne liez pas la navigation inférieure avec le contrôleur de navigation (ne faites pas ce qui est indiqué dans le guide). Gérez vous-même la transition en définissant le gestionnaire comme suit:

    bottomNav!!.setOnNavigationItemSelectedListener { item ->
        selectFragment(item)
        false
    }

Créez ensuite des transitions entre chaque fragment et gérez-les vous-même dans le gestionnaire. Voici un exemple avec 3:

private fun selectFragment(item: MenuItem) {
    if (selectedItem == -1)
        navController.navigate(item.itemId)
    else
        navController.navigate(
                when (item.itemId) {
                    R.id.interviewsFragment ->
                        if (selectedItem == R.id.personsFragment)
                            R.id.action_personsFragment_to_interviewsFragment
                        else
                            R.id.action_questionListsFragment_to_interviewsFragment
                    R.id.personsFragment ->
                        if (selectedItem == R.id.interviewsFragment)
                            R.id.action_interviewsFragment_to_personsFragment
                        else
                            R.id.action_questionListsFragment_to_personsFragment
                    R.id.questionListsFragment ->
                        if (selectedItem == R.id.interviewsFragment)
                            R.id.action_interviewsFragment_to_questionListsFragment
                        else
                            R.id.action_personsFragment_to_questionListsFragment
                    else -> item.itemId
                })

    selectedItem = item.itemId


    // uncheck the other items.
    for (i in 0 until bottomNav!!.menu.size()) {
        val menuItem = bottomNav!!.menu.getItem(i)
        if (menuItem.itemId == item.itemId) menuItem.isChecked = true
    }
}

Définissez les animations dans la carte de navigation. Voici un exemple avec les 3 fragments et l'animation se déplace vers l'élément étant celui sélectionné de sorte qu'il semble naturel:

<fragment
    Android:id="@+id/interviewsFragment"
    Android:name="com.unludo.interview.interview.list.InterviewsFragment"
    Android:label="InterviewsFragment" >
    <action
        Android:id="@+id/action_interviewsFragment_to_personsFragment"
        app:destination="@id/personsFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left" />
    <action
        Android:id="@+id/action_interviewsFragment_to_questionListsFragment"
        app:destination="@id/questionListsFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left" />
</fragment>
<fragment
    Android:id="@+id/personsFragment"
    Android:name="com.unludo.interview.persons.list.PersonsFragment"
    Android:label="PersonsFragment" >
    <action
        Android:id="@+id/action_personsFragment_to_interviewsFragment"
        app:destination="@id/interviewsFragment"
        app:enterAnim="@anim/enter_from_left"
        app:exitAnim="@anim/exit_to_right" />
    <action
        Android:id="@+id/action_personsFragment_to_questionListsFragment"
        app:destination="@id/questionListsFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left" />
</fragment>
<fragment
    Android:id="@+id/questionListsFragment"
    Android:name="com.unludo.interview.questions.lists.QuestionListsFragment"
    Android:label="QuestionListsFragment" >
    <action
        Android:id="@+id/action_questionListsFragment_to_personsFragment"
        app:destination="@id/personsFragment"
        app:enterAnim="@anim/enter_from_left"
        app:exitAnim="@anim/exit_to_right" />
    <action
        Android:id="@+id/action_questionListsFragment_to_interviewsFragment"
        app:destination="@id/interviewsFragment"
        app:enterAnim="@anim/enter_from_left"
        app:exitAnim="@anim/exit_to_right" />
</fragment>

Je pense que ce comportement pourrait être géré par le composant lui-même mais pour l'instant, je pense que nous devons le gérer à la main.

À votre santé :)

1
unludo