Sobes.tech
Middle

Comment implémenterais-tu la navigation en utilisant des boutons pour qu'elle conserve la pile ?

sobes.tech IA

Réponse de l'IA

J'utiliserais le composant Navigation Architecture.

  1. Création du NavGraph : Je définirais les Destinations (fragments ou Activity) et les Actions (transitions entre eux) dans une ressource XML.

    <?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"
        android:id="@+id/nav_graph"
        app:startDestination="@id/fragmentA"> // Point de départ
    
        <fragment
            android:id="@+id/fragmentA"
            android:name="com.example.FragmentA"
            android:label="FragmentA" >
            <action
                android:id="@+id/action_fragmentA_to_fragmentB"
                app:destination="@id/fragmentB" />
        </fragment>
        <fragment
            android:id="@+id/fragmentB"
            android:name="com.example.FragmentB"
            android:label="FragmentB" >
            <action
                android:id="@+id/action_fragmentB_to_fragmentC"
                app:destination="@id/fragmentC" />
        </fragment>
         <fragment
            android:id="@+id/fragmentC"
            android:name="com.example.FragmentC"
            android:label="FragmentC" />
    </navigation>
    
  2. Placement du NavHost : J'ajouterais un NavHost (par exemple, NavHostFragment) dans la mise en page de l'Activity, auquel je relierais le NavGraph.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph" /> // Lien vers le NavGraph
    
        <!-- Ici peuvent se trouver des boutons de navigation -->
    </LinearLayout>
    
  3. Ajout de boutons de navigation : J'utiliserais BottomNavigationView ou des boutons séparés. Pour BottomNavigationView, je le relierais à NavController.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <androidx.fragment.app.FragmentContainerView
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph" />
    
        <Button
            android:id="@+id/button_go_to_b"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Aller à B" />
    
        <Button
            android:id="@+id/button_go_to_c"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Aller à C" />
    </LinearLayout>
    
  4. Gestion des clics sur les boutons dans le code : Je récupérerais le NavController et appellerais navigate() lors du clic sur un bouton. NavController gère automatiquement la pile de retour, en conservant les Destinations précédents.

    // Dans l'Activity ou le Fragment
    import androidx.navigation.findNavController
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        val navController = findNavController(R.id.nav_host_fragment) // Récupération du NavController
    
        view.findViewById<Button>(R.id.button_go_to_b).setOnClickListener {
            navController.navigate(R.id.action_fragmentA_to_fragmentB) // Navigation via Action
        }
    
        view.findViewById<Button>(R.id.button_go_to_c).setOnClickListener {
            // Exemple de navigation directe vers un Destination, on peut utiliser action_fragmentA_to_fragmentC si disponible
             navController.navigate(R.id.fragmentC)
        }
    }
    

Pour une navigation plus complexe avec plusieurs onglets (BottomNavigationView, DrawerLayout), j'utiliserais setupWithNavController().

// Dans l'Activity avec BottomNavigationView
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val navController = findNavController(R.id.nav_host_fragment)
    val bottomNavView = findViewById<BottomNavigationView>(R.id.bottom_nav_view)
    bottomNavView.setupWithNavController(navController) // Liaison du BottomNavigationView avec NavController
}

Le composant Navigation gère par défaut la pile de navigation. Le clic sur le bouton "Retour" ramène l'utilisateur au Destination précédent dans la pile. Pour gérer le comportement de la pile lors de navigate(), on peut utiliser NavOptions avec popUpTo.