主要功能
在Android中,导航控制器(Navigation Controller)是用于管理应用程序中的导航操作的组件。它通常与Android Jetpack的导航组件一起使用,提供了一种简化的方式来处理应用程序的导航。
- 导航图:使用XML文件定义应用程序的导航结构,包括不同的目的地(Fragment、Activity等)和它们之间的关系。
- 导航操作:通过导航控制器执行导航操作,如跳转到另一个Fragment或返回上一个Fragment。
- 参数传递:支持在不同目的地之间传递参数。
- 深度链接:允许用户通过特定的URL直接导航到应用程序中的特定位置
Fragment的创建过程:
- 懒加载:导航组件采用懒加载的方式,只有在需要显示某个Fragment时,导航控制器才会创建该Fragment。这意味着在导航图中定义的Fragment不会在应用启动时全部创建,而是根据用户的导航操作动态创建。
- Fragment的生命周期:每个Fragment的生命周期遵循标准的Android Fragment生命周期。当Fragment被导航到时,它会调用
onCreateView()
等生命周期方法进行初始化。当用户返回到上一个Fragment时,当前Fragment会被销毁或暂停。 - Fragment的重用:如果用户在导航过程中多次访问同一个Fragment,导航控制器会重用已经创建的Fragment实例,而不是每次都创建新的实例。这有助于提高性能和减少内存使用。
使用步骤:
- 添加依赖:在
build.gradle
文件中添加导航组件的依赖。
implementation "androidx.navigation:navigation-fragment-ktx:2.5.3"
implementation "androidx.navigation:navigation-ui-ktx:2.5.3"
- 创建导航图:在
res/navigation
目录下创建一个XML文件,定义导航图。 - 设置导航控制器:在Activity或Fragment中获取导航控制器并设置导航图。
val navController = findNavController(R.id.nav_host_fragment)
4.执行导航:使用导航控制器执行导航操作。
navController.navigate(R.id.action_currentFragment_to_targetFragment)
5.处理返回:可以通过navController.popBackStack()
来处理返回操作。
下面是一个简单的Android应用程序示例,演示如何使用导航组件在多个Fragment之间进行导航。这个示例包含三个Fragment:FragmentA
、FragmentB
和FragmentC
。
1. 添加依赖
在build.gradle
文件中添加导航组件的依赖:
dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:2.5.3"
implementation "androidx.navigation:navigation-ui-ktx:2.5.3"
}
2. 创建导航图
在res/navigation
目录下创建一个名为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"
app:startDestination="@id/fragmentA">
<fragment
android:id="@+id/fragmentA"
android:name="com.example.app.FragmentA"
android:label="Fragment A" />
<fragment
android:id="@+id/fragmentB"
android:name="com.example.app.FragmentB"
android:label="Fragment B" />
<fragment
android:id="@+id/fragmentC"
android:name="com.example.app.FragmentC"
android:label="Fragment C" />
</navigation>
3. 创建Fragment
创建三个Fragment类:FragmentA
、FragmentB
和FragmentC
。
FragmentA.kt
class FragmentA : Fragment(R.layout.fragment_a) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.buttonToB).setOnClickListener {
findNavController().navigate(R.id.action_fragmentA_to_fragmentB)
}
}
}
FragmentB.kt
class FragmentB : Fragment(R.layout.fragment_b) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.buttonToC).setOnClickListener {
findNavController().navigate(R.id.action_fragmentB_to_fragmentC)
}
view.findViewById<Button>(R.id.buttonBackToA).setOnClickListener {
findNavController().popBackStack()
}
}
}
FragmentC.kt
class FragmentC : Fragment(R.layout.fragment_c) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.buttonBackToB).setOnClickListener {
findNavController().popBackStack()
}
}
}
4. 创建布局文件
为每个Fragment创建布局文件。
fragment_a.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="@+id/buttonToB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go to Fragment B" />
</LinearLayout>
fragment_b.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="@+id/buttonToC"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go to Fragment C" />
<Button
android:id="@+id/buttonBackToA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Back to Fragment A" />
</LinearLayout>
fragment_c.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="@+id/buttonBackToB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Back to Fragment B" />
</LinearLayout>
5. 设置导航控制器
在主Activity中设置导航控制器:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
NavigationUI.setupActionBarWithNavController(this, navController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp() || super.onSupportNavigateUp()
}
}
6. 主布局文件
在activity_main.xml
中添加NavHostFragment:
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/nav_graph"
app:defaultNavHost="true" />