How would you implement navigation using buttons so that it preserves the stack?
sobes.tech AI
Answer from AI
Would use the Navigation Architecture Component.
-
Creating NavGraph: I would define Destinations (fragments or Activities) and Actions (transitions between them) in an XML resource.
<?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"> // Starting point <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> -
Placing NavHost: I would add a
NavHost(e.g.,NavHostFragment) in the activity layout to which the NavGraph is attached.<?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" /> // Attaching NavGraph <!-- Navigation buttons can be here --> </LinearLayout> -
Adding navigation buttons: I would use
BottomNavigationViewor separate buttons. ForBottomNavigationView, I would bind it to theNavController.<?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="Go to B" /> <Button android:id="@+id/button_go_to_c" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Go to C" /> </LinearLayout> -
Handling button clicks in code: I would get an instance of
NavControllerand callnavigate()on it when a button is clicked.NavControllerautomatically manages the back stack, preserving previous Destinations.// In Activity or Fragment import androidx.navigation.findNavController override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val navController = findNavController(R.id.nav_host_fragment) // Getting NavController view.findViewById<Button>(R.id.button_go_to_b).setOnClickListener { navController.navigate(R.id.action_fragmentA_to_fragmentB) // Navigating via Action } view.findViewById<Button>(R.id.button_go_to_c).setOnClickListener { // Direct navigation to Destination, can also use action_fragmentA_to_fragmentC if available navController.navigate(R.id.fragmentC) } }
For more complex navigation with multiple tabs (BottomNavigationView, DrawerLayout), I would use setupWithNavController().
// In Activity with 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) // Binding BottomNavigationView to NavController
}
Navigation Component by default handles the back stack. Pressing the "Back" button will return the user to the previous destination in the back stack. To manage back stack behavior during navigate(), you can use NavOptions with popUpTo.