当前位置: 首页 > news >正文

Android中Navigation使用介绍

一、Navigation基础使用

1. 添加依赖 (app/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"// 可选:Safe Args 插件(类型安全参数传递)apply plugin: "androidx.navigation.safeargs.kotlin"
}
2. 创建导航图 (res/navigation/nav_main.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_main"app:startDestination="@id/homeFragment"> <!-- 固定入口 --><!-- 首页 --><fragmentandroid:id="@+id/homeFragment"android:name="com.example.app.HomeFragment"android:label="Home"tools:layout="@layout/fragment_home"><!-- 定义跳转动作 --><actionandroid:id="@+id/action_home_to_detail"app:destination="@id/detailFragment" /></fragment><!-- 详情页 --><fragmentandroid:id="@+id/detailFragment"android:name="com.example.app.DetailFragment"android:label="Detail"tools:layout="@layout/fragment_detail"><!-- 定义接收的参数 --><argumentandroid:name="itemId"app:argType="integer" /></fragment>
</navigation>
3. 设置导航宿主 (activity_main.xml)
<androidx.fragment.app.FragmentContainerViewandroid:id="@+id/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/nav_main" /> <!-- 绑定导航图 -->
4. 执行导航 (HomeFragment.kt)
class HomeFragment : Fragment() {private lateinit var binding: FragmentHomeBindingoverride fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {binding = FragmentHomeBinding.inflate(inflater, container, false)return binding.root}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 获取 NavControllerval navController = findNavController()binding.btnGoToDetail.setOnClickListener {// 方式1:基础导航// navController.navigate(R.id.action_home_to_detail)// 方式2:带参数导航(Bundle)val args = Bundle().apply {putInt("itemId", 12345)}navController.navigate(R.id.action_home_to_detail, args)// 方式3:Safe Args(推荐)// val direction = HomeFragmentDirections.actionHomeToDetail(itemId = 12345)// navController.navigate(direction)}}
}
5. 接收参数 (DetailFragment.kt)
class DetailFragment : Fragment() {// 传统方式获取参数private val itemId by lazy { arguments?.getInt("itemId", -1) ?: -1 }// Safe Args方式(需在build.gradle应用插件)// private val args: DetailFragmentArgs by navArgs()// val itemId = args.itemIdoverride fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)Log.d("DetailFragment", "Received itemId: $itemId")}
}

二、核心原理:Navigation组成架构

1. NavGraph(导航图)
  • 作用:应用导航的"地图"

  • 存储内容

    • 所有目的地(Destination)

    • 动作(Action)定义

    • 参数(Argument)声明

  • 编译时:XML 被解析为 NavGraph 对象

2. NavHost(导航宿主)
  • 实现类:通常是 NavHostFragment

  • 职责

    • 提供 Fragment 容器

    • 响应 NavController 指令

    • 管理 Fragment 切换

  • 关键特性

    app:defaultNavHost="true" <!-- 拦截返回键 -->
3. NavController(导航控制器)
  • 获取方式

    // Fragment中
    findNavController() // Activity中
    Navigation.findNavController(activity, R.id.nav_host_fragment)
  • 核心职责

    • 执行导航操作

    • 管理返回栈(BackStack)

    • 协调 Navigator

三、NavController 核心 API 详解

1. navigate(int resId, Bundle args, NavOptions navOptions)
  • 作用:导航到指定目的地

  • 参数

    • resId:目标页面ID(如 R.id.detailFragment

    • args:传递参数的 Bundle

    • navOptions:导航行为配置

  • 特点

    • 默认将新页面加入回退栈(可通过 navOptions 修改)

    • 参数传递:使用 Safe Args 插件可类型安全传参

    • 生命周期影响:目标 Fragment 会经历完整生命周期

  • 示例

// 带参数导航
val args = bundleOf("itemId" to 123)
findNavController().navigate(R.id.detailFragment, args)// 使用 NavOptions 配置
val options = NavOptions.Builder().setLaunchSingleTop(true) // 启用单例模式(但仍有重建问题).setEnterAnim(R.anim.slide_in).build()
findNavController().navigate(R.id.detailFragment, null, options)
2. popBackStack(int destinationId, boolean inclusive)
  • 作用:回退到指定页面

  • 参数

    • destinationId:目标回退页面ID

    • inclusive:是否同时弹出目标页面本身

  • 特点

    • 参数保留:回退后栈中页面保留原有参数

    • 清栈行为:当 inclusive=true 时,目标页面也被移除

    • 返回值:成功时返回 true,若目标页不在栈中返回 false

  • 示例

// 回退到首页(保留首页)
findNavController().popBackStack(R.id.homeFragment, false) // 清空回退栈直到登录页(包括登录页)
findNavController().popBackStack(R.id.loginFragment, true)
3. navigateUp()
  • 作用:向上导航(遵循导航图层级)

  • 特点

    • 优先使用导航图父节点,而非物理返回栈

    • 返回值:成功返回 true,无父级时返回 false

    • 典型场景:处理 ActionBar 的向上箭头

  • 生命周期:当前页面被销毁,目标页面重建

  • 示例

// 在 Activity 中处理向上导航
override fun onSupportNavigateUp(): Boolean {return findNavController(R.id.nav_host_fragment).navigateUp() || super.onSupportNavigateUp()
}
4. 深度链接
<fragment android:id="@+id/detailFragment"><deepLink app:uri="https://example.com/detail/{itemId}" />
</fragment>
// 处理Intent跳转
val deepLinkIntent = Intent(Intent.ACTION_VIEW, "https://example.com/detail/123".toUri())
findNavController().handleDeepLink(deepLinkIntent)

四、Navigation 的缺点及解决方案

1. 静态配置维护困难
  • 问题:所有页面需在 XML 预定义,大型项目修改成本高

  • 案例:添加新页面需修改 nav_graph.xml,可能引发冲突

2. 固定启动页不灵活
  • 问题startDestination 必须静态指定

  • 影响:无法根据条件(如登录状态)动态设置

3. Fragment 频繁重建
  • 原因:默认 FragmentNavigator 使用 replace()

  • 影响

    • 页面返回时 onCreateView() 重新执行

    • 复杂视图性能开销大

    • 状态丢失需手动保存

4. 无效的 singleTop 模式
  • 问题app:launchSingleTop="true" 仍会重建栈顶页面

  • 原因:未实现真正的实例复用

http://www.lqws.cn/news/505153.html

相关文章:

  • 跟着AI学习C#之项目实践Day5
  • 从0开始学习R语言--Day31--概率图模型
  • Blaster - Multiplayer P162-PXX
  • 系统性能优化-4 磁盘
  • 【Bluedroid】蓝牙启动之 bta_dm_enable 流程梳理 源码解析
  • 【AI落地应用实战】Chaterm:重新定义终端操作的AI智能工具
  • C# WinForm跨平台串口通讯实现
  • ffmpeg下载地址
  • 数组题解——移除元素​【LeetCode】
  • Windows驱动开发最新教程笔记2025(一)名词解释
  • Nginx SSL/TLS协议栈中配置深度解析与实践指南-优雅草卓伊凡
  • From Tranformer to Decoder ONLY
  • 云原生周刊:Argo CD v3.1 正式发布
  • PyEcharts教程(009):PyEcharts绘制水球图
  • 【HTTP】取消已发送的请求
  • Leaflet面试题200道
  • C++修炼:智能指针
  • 自然语言处理入门
  • centos7 rpm 包升级openssh至10.0版本
  • 解码成都芯谷金融中心文化科技产业园:文化+科技双轮驱动
  • 枫清科技受邀参加2025数据智能大会
  • 如何通过nvm切换本地node环境详情教程(已装过node.js更改成nvm)
  • Vue3+el-table-v2虚拟表格大数据量多选功能详细教程
  • 字节跳动开源了一款 Deep Research 项目
  • YOLO、VOC、COCO数据集格式
  • C++中的数学计算库Eigen
  • LT8311EX一款适用于笔记本电脑,扩展坞的usb2.0高速运转芯片,成对使用,延伸长度达120米
  • EXCEL中实用的一些手段——BOM汇总查询
  • 【Datawhale组队学习202506】YOLO-Master task04 YOLO典型网络模块
  • 桥头守望者