头图

Welcome to another article in the MAD Skill series In this article, we will introduce a highly sought-after feature, that is, Navigation's support for multiple return stacks. If you prefer the form of videos, click here to view video content.

Overview

Suppose your application uses BottomNavigationView . With this function, when the user selects another tab (Tab), the return stack of the current tab will be saved, and the return stack of the selected tab will be restored.

Starting from version 2.4.0-alpha01, the NavigationUI auxiliary class does not need to change any code to support multiple return stacks. In other words, if your application uses the setupWithNavController() method provided BottomNavigationView or NavigationView , you only need to update the dependent library version to enable multiple return stacks by default.

supports multiple return stacks

Let us see the actual effect through this advanced navigation example in the warehouse

The application consists of 3 tabs, each of which has its own navigation flow. In order to support multiple return stacks in the early version of navigation, we need to add a series of auxiliary functions to NavigationExtensions Through these extension functions, the application can maintain a separate NavHostFragment for each tab, and each NavHostFragment its own return stack. When the user switches tabs, the application can switch between NavHostFragment

Let's see what happens if these extension functions are removed. For this reason I deleted NavigationExtensions class, in all the places that use it are replaced NavigationUI in standard setupWithNavController() method to our BottomNavigationView connected to NavController on.

class MainActivity : AppCompatActivity() {
 
   private lateinit var navController: NavController
   private lateinit var appBarConfiguration: AppBarConfiguration
 
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
 
       val navHostFragment = supportFragmentManager.findFragmentById(
           R.id.nav_host_container
       ) as NavHostFragment
       navController = navHostFragment.navController
 
       // 使用 navController 设置 bottomNavigationView
       val bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_nav)
       bottomNavigationView.setupWithNavController(navController)
 
       // 使用 navController 设置 ActionBar 以及 3 个一级目的地页面
       appBarConfiguration = AppBarConfiguration(
           setOf(R.id.titleScreen, R.id.leaderboard,  R.id.register)
       )
       val toolbar = findViewById<Toolbar>(R.id.toolbar)
       setSupportActionBar(toolbar)
       toolbar.setupWithNavController(navController, appBarConfiguration)
   }
 
   override fun onSupportNavigateUp(): Boolean {
       return navController.navigateUp(appBarConfiguration)
   }
}

At the same time, I used the include tag to merge the three separate navigation maps into one map. Now our Activity layout only contains a NavHostFragment with a single navigation map.

<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/home">

   <include app:graph="@navigation/home"/>
   <include app:graph="@navigation/list"/>
   <include app:graph="@navigation/form"/>

</navigation>

When I run the app, this time the bottom tabs no longer maintain their state, and will reset its back stack when I switch to other tabs. Due to the removal of NavigationExtensions , the application no longer supports multiple return stacks.

Now I will update the version of the navigation and fragment dependent libraries.

// fragment 最新版本 https://developer.android.google.cn/jetpack/androidx/releases/fragment?hl=en
// navigation 最新版本 https://developer.android.google.cn/jetpack/androidx/releases/navigation?hl=en

versions.fragment = "1.4.0-alphaXXX"
versions.navigation =  "2.4.0-alphaXXX"

After Gradle sync is complete, I run the application again. At this time, when I navigate to other tabs, I can see that each tab maintains its state. Note that this behavior is enabled by default.

Finally, let's run a test to verify that everything is ok. The app already has some tests to verify the behavior of multiple return stacks. I run BottomNavigationTest and observe the operation of each bottom navigation behavior test.

Look, all our tests passed!

Summary

That's it! If your application uses BottomNavigationView or NavigationView , and you have been waiting to support multiple return stacks, all you need to do is update the navigation and fragment dependent libraries, without changing any code!

If you need further customization, there are also new APIs that support saving and restoring the return stack. Please refer to our previous tweet " Android multi-return stack technology detailed explanation ".

If you want to know more about the underlying API and what needs to be modified to support multiple return stacks, please refer to our previous tweet " Brand New Fragment: Use the New State Manager ".

Thank you for your interest in this navigation series!

Welcome to Click here to submit feedback to us, or share your favorite content or problems found. Your feedback is very important to us, thank you for your support!


Android开发者
404 声望2k 粉丝

Android 最新开发技术更新,包括 Kotlin、Android Studio、Jetpack 和 Android 最新系统技术特性分享。更多内容,请关注 官方 Android 开发者文档。