Sobes.tech
Middle

¿Cómo implementarías la navegación usando botones para que conserve la pila?

sobes.tech AI

Respuesta de la IA

Utilizaría Navigation Architecture Component.

  1. Crear NavGraph: Definiría Destinos (fragmentos o Activity) y Acciones (transiciones entre ellos) en un recurso 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"> // Punto de inicio
    
        <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. Ubicación de NavHost: Añadir NavHost (por ejemplo, NavHostFragment) en el diseño de la Activity, al que se vincula el 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" /> // Enlace al NavGraph
    
        <!-- Aquí pueden ir botones de navegación -->
    </LinearLayout>
    
  3. Agregar botones de navegación: Utilizaría BottomNavigationView o botones separados. Para BottomNavigationView, lo enlazaría con 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="Ir a B" />
    
        <Button
            android:id="@+id/button_go_to_c"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Ir a C" />
    </LinearLayout>
    
  4. Manejo de clics en botones en código: Obtener el NavController y llamar a navigate() al hacer clic en un botón. NavController gestiona automáticamente la pila de navegación, guardando destinos previos.

    // En la Activity o Fragment
    import androidx.navigation.findNavController
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        val navController = findNavController(R.id.nav_host_fragment) // Obtener NavController
    
        view.findViewById<Button>(R.id.button_go_to_b).setOnClickListener {
            navController.navigate(R.id.action_fragmentA_to_fragmentB) // Navegar mediante Action
        }
    
        view.findViewById<Button>(R.id.button_go_to_c).setOnClickListener {
            // Ejemplo de navegación directa a un destino, se puede usar action_fragmentA_to_fragmentC si existe
             navController.navigate(R.id.fragmentC)
        }
    }
    

Para navegación más compleja con varias pestañas (BottomNavigationView, DrawerLayout), usaría setupWithNavController().

// En la Activity con 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) // Enlace de BottomNavigationView con NavController
}

Navigation Component maneja automáticamente la pila de navegación. Al pulsar el botón "Atrás", el usuario regresa al destino anterior en la pila. Para gestionar el comportamiento de la pila al navegar, se puede usar NavOptions con popUpTo.