Navigation of architecture components
Navigation component is a library that can manage complex navigation, transition animation, deep link and compile time check parameter transfer among multiple screens in the application
To use Navigation, you need to build.gradle Add dependency to:
implementation 'androidx.navigation:navigation-fragment:2.2.2' implementation 'androidx.navigation:navigation-ui:2.2.2'
Simple navigation component use
1. Create an activityThe layout is as follows
<LinearLayout 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:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/primary" android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" /> <fragment android:id="@+id/my_nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/demo_navigation" /> </LinearLayout>
Three properties of fragment need to be noted.
- android:name Specify the type of Fragment as NavHostFragment
- app:navGraph Specify Navigation file
- app:defaultNavHost= The function of "true" is to let Navigation handle the return event. When clicking the return button, it does not return to the previous Activity, but returns to the previous "page". The previous "page" may be an Activity or a Fragment.
The activity code is as follows:
class DemoNavigationActivity : AppCompatActivity() { private lateinit var appBarConfiguration : AppBarConfiguration override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.demo_activity_navigation) val host: NavHostFragment = supportFragmentManager.findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment? ?: return val navController = host.navController appBarConfiguration = AppBarConfiguration(navController.graph) // Navigation monitor navController.addOnDestinationChangedListener { _, destination, _ -> val dest: String = try { resources.getResourceName(destination.id) } catch (e: Resources.NotFoundException) { Integer.toString(destination.id) } Toast.makeText(this@DemoNavigationActivity, "Navigated to $dest",Toast.LENGTH_SHORT).show() Log.d("NavigationActivity", "Navigated to $dest") } } }
Key points: get NavController and appBarConfiguration
2. Create several fragmentsA simple Fragment code is as follows
class HomeFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater,container: ViewGroup?, savedInstanceState: Bundle?): View? { setHasOptionsMenu(true) return inflater.inflate(R.layout.demo_fragment_navigation_main, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) findViewById<Button>(R.id.navigate_destination_button).setOnClickListener { getView()?.let { it -> Navigation.findNavController(it).navigate(R.id.flow_step_one_dest, null) } } } }
Important: set the click event of the button to jump
In Navigation, the page Jump is handled by NavController
Get NavController by:
- NavHostFragment.findNavController(Fragment)
- Navigation.findNavController(Activity, @IdRes int viewId)
- Navigation.findNavController(View)
Jump through NavController's navigate:
- navigate(@IdRes int resId) jumps through destinationId or actionId
- navigate(@IdRes int resId, @Nullable Bundle args) through id + parameter
- navigate(@IdRes int resId, @Nullable Bundle args, @Nullable NavOptions navOptions) through id + parameter + transition animation
A navigation map is a resource file that contains all the destinations and logical connections for your application (the latter is also known as "operations" that users can perform to navigate from one destination to another). You can use the Navigation Editor in Android Studio to manage your app's navigation map.
- Create navigation directory
- Select the project resource folder res, right-click > > New > > new resource directory
- Select navigation and click Create
A simple xml code of navigation
<?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" app:startDestination="@+id/home_dest"> <fragment android:id="@+id/home_dest" android:name="com.edgar.movie.demo.activity.navigation.HomeFragment" android:label="home" tools:layout="@layout/demo_fragment_navigation_main"> <!--<action--> <!--android:id="@+id/next_action"--> <!--app:destination="@+id/flow_step_one_dest"--> <!--app:enterAnim="@anim/slide_in_right"--> <!--app:exitAnim="@anim/slide_out_left"--> <!--app:popEnterAnim="@anim/slide_in_left"--> <!--app:popExitAnim="@anim/slide_out_right" />--> </fragment> <fragment android:id="@+id/flow_step_one_dest" android:name="com.edgar.movie.demo.activity.navigation.FlowStepFragment" tools:layout="@layout/demo_fragment_flow_step_one"> <argument android:name="flowStepNumber" app:argType="integer" android:defaultValue="1"/> <action android:id="@+id/next_action" app:destination="@+id/flow_step_two_dest"> </action> </fragment> <fragment android:id="@+id/flow_step_two_dest" android:name="com.edgar.movie.demo.activity.navigation.FlowStepFragment" tools:layout="@layout/demo_fragment_flow_step_two"> <argument android:name="flowStepNumber" app:argType="integer" android:defaultValue="2"/> <action android:id="@+id/next_action" app:popUpTo="@id/home_dest"> </action> </fragment> </navigation>
Properties in navigation:
- The id of the android xml file navigation is very important. We need to reference it in the activity's xml layout. Remember to write it down and don't forget
- app:startDestination : the first page loaded for the second time, which is very important, is generally the first fragment
Properties in fragment:
- android:id="@+id/one" each fragment node needs to have its own ID, target ID
Two android:name Corresponding Fragment
- android:label Label information
- tools:layout= "@layout/fragment_ "Blank" layout
Properties in action (responsible for writing jump actions):
- android:id ID of Jump Action
- app:destination Target fragment of jump