Article directory
Code address:
- CSDN (code snapshot of this blog | Recommended download 0 credits): https://download.csdn.net/download/han1202012/87936252
- GitHub (maybe covered): https://github.com/han1202012/Navigation
1. Description of the core points of Navigation navigation component development
1. The creation order of each sub-component of Navigation
The main points of the creation order of each subcomponent of the Navigation navigation component are as follows:
- First, create the navigated Fragment page code and the corresponding layout file;
- Then, create a corresponding Navigation Graph based on the created Fragment , and configure the jump action between Fragments in it;
- Then, create a NavHostFragment component that displays content based on the created Navigation Graph ;
- Finally, get the NavController component in the Activity to realize the jump between Fragments;
It must be created according to the above process: Fragment -> Navigation Graph -> NavHostFragment -> NavController , the latter components depend on the previous components, otherwise the Navigation navigation cannot be realized;
2. Import Navigation dependencies
To use the Navigation component, you must import Navigation dependencies, and different development languages import different dependencies:
- Use the Java language to develop Navigation navigation, and import the following dependencies:
dependencies {
implementation 'androidx.navigation:navigation-fragment:2.2.2'
implementation 'androidx.navigation:navigation-ui:2.2.2'
}
- Use Kotlin language to develop Navigation navigation, and import the following dependencies:
dependencies {
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'
}
If you do not import dependencies and use Navigation directly, a "failed to add navigation dependency" exception message will be reported;
3. Create Fragment and layout files
Right-click the code package to create a Fragment, select the "New / Fragment / Fragment (Blank)" option , you can directly create a Fragment, and generate the corresponding Fragment layout file;
4. Create Navigation Graph
Right-click the res resource directory, and in the pop-up drop-down menu, select the "New / Android Resource File" option,
In the "Resource Type" option, select the "Navigation" option. After selection, the "Root element" and "Directory name" options will be automatically set. Developers only need to set a "File name";
When creating a Navigation Graph, you need to specify which Fragments to include in navigation management, which is why you need to create a Fragment before creating a Navigation Graph;
After creating the Navigation Graph, in the Design mode, click the "New Destination" button to add the Fragment page to be navigated, where both FragmentA and FragmentB are included in the Navigation navigation management;
After creation, you can drag the mouse to set the jump relationship between the two Fragments in the Navigation Graph, FragmentA jumps to FragmentB, and FragmentB jumps to FragmentA;
In this way, the creation of the Navigation Graph is completed, and then the above two jumps will be called through the NavController to realize the jump between the two Fragments respectively;
5. Create NavHostFragment
NavHostFragment is set in the layout file of the Activity,<fragment/>
generally a android:name="androidx.navigation.fragment.NavHostFragment"
property is set for the label, and the fragment becomes NavHostFragment;
<fragment
android:id="@+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph" />
It is not recommended to drag the NavHostFragment under the Container to the layout in the Design graphical interface, the generated code is wrong;
The specific error content is analyzed in detail in the error record column, and will not be repeated here;
6. Create NavController
Get the NavController by calling the findNavController function in the Activity , and then navigate through the NavController variable;
The management operation of fragmentContainerView component is done through NavController;
// fragmentContainerView 组件的 管理 操作通过 NavController 完成
// 对应的就是 navController 实例变量
val navController = findNavController(this, R.id.fragment)
NavigationUI.setupActionBarWithNavController(this, navController)
7. Fragment realizes navigation operation
In the Fragment interface, jump to another Fragment interface by clicking the button;
First, get the NavigationController, and get the NavigationController instance object by calling the Navigation.findNavController function ;
Then, call NavigationController#navigate to navigate, and pass in the id of the specific action in the Navigation Graph;
// 获取 NavigationController
val navController = Navigation.findNavController(it)
// 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走
navController.navigate(R.id.action_fragmentA_to_fragmentB)
R.id.action_fragmentA_to_fragmentB
The corresponding action in the above code is as follows:
<fragment
android:id="@+id/fragmentA"
android:name="kim.hsl.nav.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a" >
<action
android:id="@+id/action_fragmentA_to_fragmentB"
app:destination="@id/fragmentB" />
</fragment>
2. Complete code example of Navigation navigation component
Code address:
- CSDN (code snapshot of this blog | Recommended download 0 credits): https://download.csdn.net/download/han1202012/87936252
- GitHub (maybe covered): https://github.com/han1202012/Navigation
1. Fragment complete source code
Create 2 Fragments, set a button for each Fragment, and jump between the two Fragments;
FragmentA source code
The core jump source code in Fragment is as follows, first get NavigationController, and then call NavigationController#navigate to jump to FragmentB page;
// 获取 NavigationController
val navController = Navigation.findNavController(it)
// 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走
navController.navigate(R.id.action_fragmentA_to_fragmentB)
Complete source code:
package kim.hsl.nav
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.fragment.app.Fragment
import androidx.navigation.Navigation
import androidx.navigation.Navigation.findNavController
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [FragmentA.newInstance] factory method to
* create an instance of this fragment.
*/
class FragmentA : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_a, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment FragmentA.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
FragmentA().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val button = view.findViewById<Button>(R.id.button)
button.setOnClickListener {
// 获取 NavigationController
val navController = Navigation.findNavController(it)
// 按照 action_fragmentA_to_fragmentB 对应的 action 的导航路线走
navController.navigate(R.id.action_fragmentA_to_fragmentB)
}
}
}
FragmentA layout file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentA">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="跳转到 B"
android:onClick="onClick" />
</FrameLayout>
FragmentB source code
The core jump source code in Fragment is as follows, first get NavigationController, and then call NavigationController#navigate to jump to FragmentB page;
// 获取 NavigationController
val navController = Navigation.findNavController(it)
// 按照 action_fragmentB_to_fragmentA 对应的 action 的导航路线走
navController.navigate(R.id.action_fragmentB_to_fragmentA)
The complete code is as follows:
package kim.hsl.nav
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.navigation.Navigation
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [FragmentB.newInstance] factory method to
* create an instance of this fragment.
*/
class FragmentB : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_b, container, false)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment FragmentB.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
FragmentB().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val button = view.findViewById<Button>(R.id.button)
button.setOnClickListener {
// 获取 NavigationController
val navController = Navigation.findNavController(it)
// 按照 action_fragmentB_to_fragmentA 对应的 action 的导航路线走
navController.navigate(R.id.action_fragmentB_to_fragmentA)
}
}
}
FragmentB layout file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentB">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="跳转到 A"
android:onClick="onClick" />
</FrameLayout>
2. Navigation Graph source code
Create a Navigation Graph, import two Fragments, and set the jump relationship between the two Fragments in the Navigation Graph, FragmentA jumps to FragmentB, and FragmentB jumps to FragmentA;
<?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_graph"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="kim.hsl.nav.FragmentA"
android:label="fragment_a"
tools:layout="@layout/fragment_a" >
<action
android:id="@+id/action_fragmentA_to_fragmentB"
app:destination="@id/fragmentB" />
</fragment>
<fragment
android:id="@+id/fragmentB"
android:name="kim.hsl.nav.FragmentB"
android:label="fragment_b"
tools:layout="@layout/fragment_b" >
<action
android:id="@+id/action_fragmentB_to_fragmentA"
app:destination="@id/fragmentA" />
</fragment>
</navigation>
3. Add the NavHostFragment component to the Activity layout file
NavHostFragment is set in the layout file of the Activity, <fragment/>
generally a android:name="androidx.navigation.fragment.NavHostFragment"
property is set for the label, and the fragment becomes NavHostFragment;
<fragment
android:id="@+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph" />
The complete layout file code is as follows:
<?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">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<fragment
android:id="@+id/fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
4. Get NavController in the Activity code and navigate
Get the NavController by calling the findNavController function in the Activity, and then navigate through the NavController variable;
The management operation of fragmentContainerView component is done through NavController;
// fragmentContainerView 组件的 管理 操作通过 NavController 完成
// 对应的就是 navController 实例变量
val navController = findNavController(this, R.id.fragment)
NavigationUI.setupActionBarWithNavController(this, navController)
The complete code is as follows:
package kim.hsl.nav
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.Navigation.findNavController
import androidx.navigation.ui.NavigationUI
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// fragmentContainerView 组件的 管理 操作通过 NavController 完成
// 对应的就是 navController 实例变量
val navController = findNavController(this, R.id.fragment)
NavigationUI.setupActionBarWithNavController(this, navController)
}
}
5. Operation effect
Click the button on the FragmentA page to jump to the FragmentB page, click the button on the FragmentB page to jump to the FragmentA page;
Code address:
- CSDN (code snapshot of this blog | Recommended download 0 credits): https://download.csdn.net/download/han1202012/87936252
- GitHub (maybe covered): https://github.com/han1202012/Navigation