当前位置: 首页 > 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" 仍会重建栈顶页面

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

相关文章:

  • 可不可以自己做网站网络营销策划方案模板
  • wordpress启用静态东莞网站推广及优化
  • 云服务器搭建网站教程企业网络
  • 做网站卖狗挣钱吗营销公司排行
  • 上海网站建设 觉策动力电商数据网站
  • 可视化网站建设软件有哪些网站怎么弄
  • QT Creator的快捷键设置 复制当前行 ctrl+d 删除当前行 ctrl +y,按照 AS设置
  • 13.5-13.8. 计算机视觉【2】
  • jar 包如何下载
  • 网页变形记:响应式设计如何在手机里 “七十二变”
  • 【unitrix】 4.3 左移运算(<<)的实现(shl.rs)
  • 医疗AI数智立体化体系V2.0泛化多模块编程操作手册--架构师版(下)
  • Docker Compose与私有仓库部署
  • 多项目资料如何统一归档与权限管理
  • 2023/7 N2 jlpt词汇
  • uniapp实现远程图片下载到手机相册功能
  • DD3118S:USB3.0+Type-c双头TF/SD二合一高速0TG多功能手机读卡器ic
  • 【单元测试】单元测试的定义和作用
  • mysql 数据库连接 -h localhost 和 -h 127.0.0.1 区别是什么
  • 【AI时代速通QT】第三节:Linux环境中安装QT并做测试调试
  • C++修炼:异常
  • stm32万年历仿真+keil5程序
  • DeepSeek 和 GPT 系列模型针对越狱攻击的安全评估
  • Lombok注解 - 提高Java开发效率
  • phpstudy apache伪静态.htaccess文件置空丢失问题解决
  • WPF CommunityToolkit.Mvvm