Android Navigation 组件(用于Fragment间的跳转)
用于解决Fragment之间的跳转,传参的问题
1添加依赖 (build.gradle):
dependencies {def nav_version = "2.7.7" // 使用当前最新稳定版implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
}
2创建导航地图
在 res/navigation/ 文件夹下新建一个 XML 文件(如 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"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/nav_graph"app:startDestination="@id/homeFragment"> <!-- 指定入口页面 --><!-- 定义目标1:首页 --><fragmentandroid:id="@+id/homeFragment"android:name="com.example.app.HomeFragment"android:label="Home"tools:layout="@layout/fragment_home"><!-- 定义从homeFragment到detailFragment的动作 --><actionandroid:id="@+id/action_home_to_detail"app:destination="@id/detailFragment" /></fragment><!-- 定义目标2:详情页 --><fragmentandroid:id="@+id/detailFragment"android:name="com.example.app.DetailFragment"android:label="Detail"tools:layout="@layout/fragment_detail" />
</navigation>
3设置导航宿主 (NavHostFragment):
在你的主 Activity 的布局文件 (activity_main.xml) 中,放置一个 “容器” (NavHostFragment)。
◦ 这个容器告诉 Navigation 组件:“在这个区域里显示的 Fragment,都由我来管理它们的进出和切换”。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><!-- 关键!NavHostFragment容器 --><androidx.fragment.app.FragmentContainerViewandroid:id="@+id/nav_host_fragment"android:name="androidx.navigation.fragment.NavHostFragment" <!-- 指定实现类是NavHostFragment -->android:layout_width="match_parent"android:layout_height="match_parent"app:defaultNavHost="true" <!-- 很重要!让这个NavHost处理系统返回键 -->app:navGraph="@navigation/nav_graph" /> <!-- 关联之前定义的导航图 -->
</FrameLayout>
4执行导航 (使用 NavController):
在 HomeFragment 中,当按钮被点击时,你需要找到 “导航仪” (NavController)。
这个导航仪知道当前在哪个位置 (NavHostFragment),也有一张地图 (nav_graph.xml)。你告诉它:“执行 action_home_to_detail 这个动作”。
Kotlin 示例 (在 Fragment 中):
class HomeFragment : Fragment() {override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val navController = findNavController() // 获取绑定到当前视图的NavControllerbinding.goToDetailButton.setOnClickListener {// 使用导航控制器执行指定的导航动作navController.navigate(R.id.action_home_to_detail)}}
}
5 传递参数 (Arguments):
在导航图中定义参数:
<fragmentandroid:id="@+id/detailFragment"... ><argumentandroid:name="itemId"app:argType="integer" /> <!-- 定义需要接收一个整数参数 itemId -->
</fragment>
在发起导航时传递参数:
binding.goToDetailButton.setOnClickListener {// 创建一个 Bundle 或使用 Safe Args (推荐,见下面概念)val bundle = bundleOf("itemId" to 12345)navController.navigate(R.id.action_home_to_detail, bundle)
}
在 DetailFragment 中获取参数:
val itemId = arguments?.getInt("itemId") ?: 0 // 或者使用 Safe Args
