Single Activity + multi Fragment mode
Since I know this move, I am basically reluctant to use activity. fragment can be quickly created and managed, page Jump can be reasonably designed, cool jump animation can be designed, and some operations can be managed uniformly.
- Replace Activity with Fragment
In the past, activity was used as a page most of the time, Fragment as a sub page in a page (it was called fragment at that time). Basically, most functions are realized by activity. For example, the old version of Taobao app has hundreds of activities, which Caton didn't want at that time. With the technical iteration, we found that the performance consumed by the creation, switching and destruction of Activiy is much greater than that of fragment, and fragment can replace activity to realize most functions now.
- Use Activity as a container
The single activity + multiple fragments mode I understand does not mean that an App must have only one activity. For some business-related scenarios, it can be integrated into a single activity + multiple fragments module, using the activity as a container for fragments and allowing fragments to do UI rendering.
- Manage Fragment stack
We can use navigation to manage fragments. Jumping between fragments and stack management are easy. Navigation can also set switching animation and data transfer between pages.
Navigation component
Navigation is one of the Jetpack components. iOS used this jump method a long time ago. At that time, I wondered why Android didn't exist. It wasn't long before navigation was available.
Navigation can be understood as a container for managing fragments, in which each fragment can jump arbitrarily,
Foundation use:
- We need to create a Fragment container in the layout:
<androidx.fragment.app.FragmentContainerView android:id="@+id/main_fragment_container" android:layout_width="match_parent" android:layout_height="0dp" android:name="androidx.navigation.fragment.NavHostFragment" app:defaultNavHost="true" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/nav_main"/>
- Create navigation XML file
<?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" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/navigation_main" app:startDestination="@+id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.example.mvvm_develop.MainFragment" android:label="MainFragment" /> </navigation>
- Using NavController
val navController = (childFragmentManager.findFragmentById(R.id.module_fragment_container) as NavHostFragment).navController //Jump navController.navigate(R.id.mainFragment)
Some specific parameters and usage:
navGraph
This value points to the xml file, where we can define fragment, jump behavior, destination, etc.
Create and add fragments:

Create jump behavior:

Animation, destination, return stack configuration:

NavController
It literally means navigation controller. NavController can control jump, return, animation, monitoring and other operations. We can use it to jump flexibly, and Google has made some mistakes Navigation Demo Demonstrates how to work with the Toolbar and the bottom navigation bar.
I won't explain the specific usage here. Many articles have it, and you can also refer to it Official website.
Problems with Navigation:
Re walk the life cycle
There is a problem with Navigation: Fragment fallback and reroute the life cycle. This problem may be that Google wants Fragment and activity to have the same working mode. The single reroute life cycle is really annoying. We can customize NavHostFragment to fix this problem. For details, please refer to Project code
After modification, use the following:
android:name="androidx.navigation.fragment.NavHostFragment" Modified for our custom NavHostFragment: android:name="com.example.baselibrary.navigation.NavHostFragment" <fragment android:id="@+id/navigation_main" android:name="com.example.baselibrary.navigation.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_main"/>
Using Navigation in componentization
We usually use the bottom navigation bar to divide the app into different functions. These are separate modules, but how to jump between modules in navigation?
For example:

The layout file is a FragmentContainerView+BottomNavigationView. You need to switch to different moduel pages when switching the following buttons. First, we regard different moduels as a "single activity + multiple fragments" module, or we can omit the activity.
Mode 1:
In google's demo, create a main in MainActivity_ navGraph, which contains navgraphs of different child modues, as follows:
<?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_module" app:startDestination="@+id/navi_home"> <include app:graph="@navigation/navi_home"/> <include app:graph="@navigation/navi_collection"/> <include app:graph="@navigation/navi_center"/> </navigation>
navi_home ,navi_collection ,navi_center is the navGraph file in the child moduel, which requires it to specify startDestination and can only jump to startDestination
Use with BottomNavigationView:
val navController = (childFragmentManager.findFragmentById(R.id.module_fragment_container) as NavHostFragment).navController setupWithNavController(binding.bottomNav,navController)
In this way, it is possible to switch between moduel s, but I found that this method reinitializes every time naviagtion is switched, resulting in high performance consumption.
Maybe I'm using the wrong posture?
Mode 2:
Because the app module itself depends on each sub module, we can directly use the fragments in the sub modules in navGraph. Just add the main fragments of each module to the main page:
<?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_module" app:startDestination="@+id/navi_home"> <fragment android:id="@+id/navi_home" android:name="com.xlu.module_tab1.HomeFragment" android:label="HomeFragment" /> <fragment android:id="@+id/navi_collection" android:name="com.xlu.module_collection.FragmentCollection" android:label="CenterFragment" /> <fragment android:id="@+id/navi_center" android:name="com.xlu.module_center.CenterFragment" android:label="FragmentCollection" /> </navigation>
Just switch the Fragment directly when switching the bottom state:
val navController = (childFragmentManager.findFragmentById(R.id.module_fragment_container) as NavHostFragment).navController binding.bottomNav.setOnItemSelectedListener(object :NavigationBarView.OnItemSelectedListener{ override fun onNavigationItemSelected(item: MenuItem): Boolean { navController.navigate(item.itemId) return true } })
If you are lazy, you can set the id in the menu used by BottomNavigationView to be the same as that in navGraph. Ha ha ha ha ha
Basically, ARouter+Navigation can meet most of the page Jump requirements, but there are still some difficulties, that is, how to control the navGraph between different modues. For the time being, I don't think of a good solution (it can be realized by providing interface services mentioned above). After all, Navigation doesn't intend to prepare for componentization.
Related videos:
Practical collection of value 100w+Android project: detailed explanation of MVVM
Zero foundation of Android development from entry to mastery: MVVM practice