preface

This is the Jetpack Navigation tutorial. It includes everything from getting started to faQs to sample projects.

Navigation and its use

Navigation is one of Android Jetpack components, which is mainly used for Fragment routing Navigation framework. Through Navigation, we can design a single Activity application architecture.

Navigation consists of the following three key components:

  • NavHost: displayFragmentThe container.
  • NavControllerIn:NavHostObject to manage application navigation in.
  • Navigation diagram: XML resources that configure all navigation-related information. Like the ones we useAndroidManifest.xmlSimilar.

Therefore, the use of Navigation is to configure Fragment information in the Navigation chart and tell the NavController to navigate to a specific target, and the NavController will display the target in NavHost.

Introduction to use

Please refer to the applicationbuild.gradleAdd the following dependencies to the file:

dependencies {
  val nav_version = "2.3.5"
  // Kotlin
  implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
  implementation("androidx.navigation:navigation-ui-ktx:$nav_version")}Copy the code

To add a navigation chart, do the following:

  1. In the “Project” window, right-clickresDirectories, and then select them in turnNew > Android Resource File. The system displaysNew Resource FileThe dialog box.
  2. Enter a name in the File name field, for example “nav_graph”.
  3. Select Navigation from the Resource Type drop – down list, and click OK.

When you add your first navigation diagram, Android Studio creates a Navigation resource directory in the RES directory. This directory contains your navigation graph resource files (for example, nav_graph.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">

</navigation>
Copy the code

Add NavHost to the Activity

Please note the following points:

  • android:nameAttribute containsNavHostThe class name of the implementation.
  • app:navGraphProperty will beNavHostFragmentAssociated with the navigation diagram. The navigation chart will be hereNavHostFragmentTo specify all destinations that the user can navigate to.
  • app:defaultNavHost="true"Properties ensure that yourNavHostFragmentIntercepts the system back button. Note that there can only be one defaultNavHost. If there are multiple hosts in the same layout (for example, a two-pane layout), be sure to specify only one defaultNavHost.
<? xml version="1.0" encoding="utf-8"? ><androidx.constraintlayout.widget.ConstraintLayout
    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"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        ./>

     <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph" /> 

    <com.google.android.material.bottomnavigation.BottomNavigationView
        ./>

</androidx.constraintlayout.widget.ConstraintLayout>
Copy the code

Adds and navigates to the navigation diagram to the destination

In the navigation diagram, actions are represented by the

element. The operation should contain at least its own ID and the ID of the destination to which the user should go.

<? xml version="1.0" encoding="utf-8"? ><navigation xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android"
    app:startDestination="@id/blankFragment">
    <fragment
        android:id="@+id/blankFragment"
        android:name="com.example.cashdog.cashdog.BlankFragment"
        android:label="@string/label_blank"
        tools:layout="@layout/fragment_blank" >
        <action
            android:id="@+id/action_blankFragment_to_blankFragment2"
            app:destination="@id/blankFragment2" />
    </fragment>
    <fragment
        android:id="@+id/blankFragment2"
        android:name="com.example.cashdog.cashdog.BlankFragment2"
        android:label="@string/label_blank_2"
        tools:layout="@layout/fragment_blank_fragment2" />
</navigation>
Copy the code

Navigation to the destination is done using NavController, which is an object that manages application navigation in NavHost. Navigate (int) accepts the resource ID of the operation or destination as a parameter.

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
navController.navigate(R.id.action_blankFragment_to_blankFragment2)
Copy the code

Navigation chart rules

  1. Navigation diagrams can be passed betweenidJump to the corresponding navigation diagramstartDestination
  2. It can be passed in the same navigation chartactionJump to each other
  3. Deep links can be used to jump between different navigation diagrams

The above is the basic use of Navigation, other details can be used to look website Navigation component introduction | Android Developers

Q&A

We know a little bit about Navigation from the above, but there are a few minor issues with Navigation when you follow the documentation.

Since Navigation replaces the Fragment by replacing it with a new one, every time the Fragment is switched, the problem arises.

Repeat request data

Since our project uses Navigation, the Jetpack family bucket is definitely a must. Fragment reconstruction does not cause the ViewModel to be destroyed, so the LiveData data is still saved. After the page is rebuilt, the data will be re-rendered to the page, so we don’t feel visually that the page has been rebuilt, but the corresponding initialization logic will continue to execute and request the data again. This results in a waste of resources. Now that you know why, how can you avoid the problem?

The simplest way to do this is to add a null judgment to the request data as follows:

if (viewModel.data.value == null) {
    viewModel.getData()
}
Copy the code

At first glance, I think this plan is very low. Please don’t worry about listening to me. I have also used other solutions before, such as wrapping LiveData, which is unacceptable as business needs change and you have to maintain it. In the end, the simpler you are, the less you can go wrong (UNIX design philosophy).

The transition animation is stuck

The reason for the transition animation to get stuck is the Fragment reconstruction. After the Fragment reconstruction, the page needs to be rerendered. Now that you know why, how can you avoid the problem?

The easiest way to do this is to render the page after the animation has been executed, as follows:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    view.postDelayed({
        initLoad()
    }, delayedLoad) //delayedLoad is the set time for the transition animation
}
Copy the code

Still UNIX design philosophy, of course, the above scheme is not the only solution, other schemes please search for learning ha 😃

(PS: Why don’t the authorities solve these problems? My personal guess is that the authorities haven’t found an elegant solution yet, look forward to the optimization of the subsequent version 😏)

The sample project

  • Making: fragmject

Thanks

That’s all for this article. If you have any questions, please point them out and we will make progress together. If you like it, please give me a thumbs-up. Your encouragement is my motivation to move forward. Thank you ~ ~