404 lines
8.8 KiB
Markdown
404 lines
8.8 KiB
Markdown
# 🚀 Navigation 高级功能更新总结
|
||
|
||
## 📌 更新概述
|
||
|
||
已添加高级的 Navigation 扩展和工具类,提供优雅的 DSL 风格 API 来管理应用导航。
|
||
|
||
**新增内容**:
|
||
- ✅ `NavigationExt.kt` - 核心扩展和工具类
|
||
- ✅ `AppNavigation.kt` - 应用导航图构建器
|
||
- ✅ `NavigationExample.kt` - 完整的使用示例
|
||
- ✅ `ADVANCED_NAVIGATION.md` - 详细的使用文档
|
||
- ✅ 更新 `MainActivity.kt` - 使用新的导航 API
|
||
|
||
---
|
||
|
||
## 🎯 核心 API
|
||
|
||
### 1. Routes 常量对象
|
||
|
||
```kotlin
|
||
object Routes {
|
||
const val HOME = "home"
|
||
const val SETTINGS = "settings"
|
||
}
|
||
```
|
||
|
||
### 2. NavigationEvent 密封类
|
||
|
||
```kotlin
|
||
sealed class NavigationEvent {
|
||
object NavigateToHome : NavigationEvent()
|
||
object NavigateToSettings : NavigationEvent()
|
||
object NavigateUp : NavigationEvent()
|
||
data class NavigateToRoute(val route: String) : NavigationEvent()
|
||
}
|
||
```
|
||
|
||
### 3. NavigationManager 工具类
|
||
|
||
```kotlin
|
||
// 安全导航(防止重复点击)
|
||
NavigationManager.navigateSafe(navController, route)
|
||
|
||
// 导航并清理 Back Stack
|
||
NavigationManager.navigateWithClear(navController, route, popUpTo)
|
||
|
||
// 处理导航事件
|
||
NavigationManager.handleNavigationEvent(navController, event)
|
||
```
|
||
|
||
### 4. NavController 扩展方法
|
||
|
||
```kotlin
|
||
// 快速方法
|
||
navController.navigateToHome()
|
||
navController.navigateToSettings()
|
||
navController.navigateSafe(route)
|
||
navController.navigateAndClear(route, popUpTo)
|
||
```
|
||
|
||
### 5. NavigationHelper 类
|
||
|
||
```kotlin
|
||
// 处理菜单项
|
||
navigationHelper.handleMenuItemClick(itemId)
|
||
|
||
// 处理返回按钮
|
||
navigationHelper.handleBackPressed()
|
||
|
||
// 检查状态
|
||
navigationHelper.getCurrentRoute()
|
||
navigationHelper.isAtTopDestination(route)
|
||
```
|
||
|
||
---
|
||
|
||
## 💻 快速使用示例
|
||
|
||
### 示例 1:简单导航
|
||
|
||
```kotlin
|
||
// 使用快捷方法
|
||
button.setOnClickListener {
|
||
navController.navigateToSettings()
|
||
}
|
||
```
|
||
|
||
### 示例 2:安全导航
|
||
|
||
```kotlin
|
||
// 防止快速点击导致的多次导航
|
||
button.setOnClickListener {
|
||
navController.navigateSafe(Routes.HOME)
|
||
}
|
||
```
|
||
|
||
### 示例 3:ViewModel 中的导航
|
||
|
||
```kotlin
|
||
class AppViewModel : ViewModel() {
|
||
private val _navigationEvent = MutableLiveData<NavigationEvent>()
|
||
val navigationEvent: LiveData<NavigationEvent> = _navigationEvent
|
||
|
||
fun goToSettings() {
|
||
_navigationEvent.value = NavigationEvent.NavigateToSettings
|
||
}
|
||
}
|
||
|
||
// 在 Fragment 中观察
|
||
viewModel.navigationEvent.observe(viewLifecycleOwner) { event ->
|
||
NavigationManager.handleNavigationEvent(navController, event)
|
||
}
|
||
```
|
||
|
||
### 示例 4:Back Stack 管理
|
||
|
||
```kotlin
|
||
// 导航并清理历史记录
|
||
navController.navigateAndClear(
|
||
route = Routes.HOME,
|
||
popUpTo = Routes.SETTINGS
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 📂 新增文件
|
||
|
||
### 1. 核心库文件
|
||
|
||
**NavigationExt.kt** (250 行)
|
||
- Routes 常量对象
|
||
- NavigationEvent 密封类
|
||
- NavigationManager 工具类
|
||
- NavController 扩展方法
|
||
- NavigationHelper 类
|
||
|
||
**AppNavigation.kt** (100 行)
|
||
- 应用导航图构建函数
|
||
- 路由定义
|
||
- 导航扩展方法
|
||
|
||
### 2. 示例文件
|
||
|
||
**NavigationExample.kt** (300 行)
|
||
- AppViewModel 示例
|
||
- Fragment 使用示例
|
||
- 链式导航示例
|
||
- 条件导航示例
|
||
- 完整使用演示
|
||
|
||
### 3. 文档文件
|
||
|
||
**ADVANCED_NAVIGATION.md**
|
||
- 完整的 Navigation 高级用法指南
|
||
- 代码示例
|
||
- 最佳实践
|
||
- 测试方法
|
||
|
||
---
|
||
|
||
## 🔄 使用流程
|
||
|
||
### 在 Activity 中使用
|
||
|
||
```kotlin
|
||
class MainActivity : AppCompatActivity() {
|
||
private lateinit var navController: NavController
|
||
private lateinit var navigationHelper: NavigationHelper
|
||
|
||
override fun onCreate(savedInstanceState: Bundle?) {
|
||
super.onCreate(savedInstanceState)
|
||
setContentView(R.layout.activity_main)
|
||
setupNavigation()
|
||
}
|
||
|
||
private fun setupNavigation() {
|
||
val navHostFragment = supportFragmentManager
|
||
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||
navController = navHostFragment.navController
|
||
navigationHelper = NavigationHelper(navController)
|
||
}
|
||
|
||
override fun onBackPressed() {
|
||
if (!navigationHelper.handleBackPressed()) {
|
||
@Suppress("DEPRECATION")
|
||
super.onBackPressed()
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 在 Fragment 中使用
|
||
|
||
```kotlin
|
||
class HomeFragment : Fragment() {
|
||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||
super.onViewCreated(view, savedInstanceState)
|
||
|
||
val navController = findNavController()
|
||
|
||
// 导航到设置
|
||
view.findViewById<Button>(R.id.settings_button).setOnClickListener {
|
||
navController.navigateToSettings()
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## ✨ 主要特性
|
||
|
||
### 1. 防止重复导航
|
||
```kotlin
|
||
// 自动检查当前目的地,防止多次导航
|
||
navController.navigateSafe(Routes.HOME)
|
||
```
|
||
|
||
### 2. Back Stack 管理
|
||
```kotlin
|
||
// 导航同时清理指定位置之前的 back stack
|
||
navController.navigateAndClear(Routes.HOME, Routes.SETTINGS)
|
||
```
|
||
|
||
### 3. 事件驱动
|
||
```kotlin
|
||
// 使用密封类定义所有导航事件
|
||
// 便于在 ViewModel 中管理导航
|
||
NavigationManager.handleNavigationEvent(navController, event)
|
||
```
|
||
|
||
### 4. 异常处理
|
||
```kotlin
|
||
// 所有导航操作都有异常处理
|
||
try {
|
||
navController.navigate(route)
|
||
} catch (e: Exception) {
|
||
e.printStackTrace()
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📊 API 对比
|
||
|
||
### 之前 (直接使用 NavController)
|
||
```kotlin
|
||
// ❌ 容易出错,无保护
|
||
button.setOnClickListener {
|
||
navController.navigate(R.id.settingsFragment)
|
||
}
|
||
```
|
||
|
||
### 之后 (使用新 API)
|
||
```kotlin
|
||
// ✅ 安全、简洁、可维护
|
||
button.setOnClickListener {
|
||
navController.navigateToSettings()
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 最佳实践
|
||
|
||
### ✅ 推荐做法
|
||
|
||
1. **使用常量对象** - `Routes` 集中管理路由
|
||
2. **使用扩展方法** - 快速便捷的导航
|
||
3. **使用 NavigationManager** - 统一的导航处理
|
||
4. **安全导航** - 始终使用 `navigateSafe()`
|
||
5. **事件驱动** - 在 ViewModel 中使用 NavigationEvent
|
||
|
||
### ❌ 避免做法
|
||
|
||
1. **硬编码路由** - 使用 `Routes.HOME` 替代
|
||
2. **直接调用导航** - 使用扩展方法
|
||
3. **忽略异常** - 始终处理异常
|
||
4. **快速重复点击** - 使用 `navigateSafe()`
|
||
|
||
---
|
||
|
||
## 🧪 测试示例
|
||
|
||
```kotlin
|
||
@Test
|
||
fun testSafeNavigation() {
|
||
val navController = mockk<NavController>()
|
||
navController.currentDestination?.route = Routes.HOME
|
||
|
||
NavigationManager.navigateSafe(navController, Routes.SETTINGS)
|
||
|
||
verify {
|
||
navController.navigate(Routes.SETTINGS, any())
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 📚 完整示例
|
||
|
||
查看 `NavigationExample.kt` 了解:
|
||
- ✅ 直接使用 NavController 的快捷方法
|
||
- ✅ 使用 NavigationManager 处理事件
|
||
- ✅ 安全导航防止重复点击
|
||
- ✅ 导航并清理 Back Stack
|
||
- ✅ 从 ViewModel 观察导航事件
|
||
- ✅ 按钮点击导航
|
||
- ✅ 链式导航
|
||
- ✅ 条件导航
|
||
|
||
---
|
||
|
||
## 📖 完整文档
|
||
|
||
详细信息请查看 `ADVANCED_NAVIGATION.md`:
|
||
- 核心概念讲解
|
||
- 详细的代码示例
|
||
- 高级导航场景
|
||
- 最佳实践指南
|
||
- 测试方法
|
||
- 常见问题解答
|
||
|
||
---
|
||
|
||
## 🔗 关键类和方法速查表
|
||
|
||
| 类/对象 | 用途 | 示例 |
|
||
|--------|------|------|
|
||
| `Routes` | 路由常量 | `Routes.HOME` |
|
||
| `NavigationEvent` | 导航事件 | `NavigationEvent.NavigateToHome` |
|
||
| `NavigationManager` | 导航工具 | `NavigationManager.navigateSafe()` |
|
||
| `NavController.navigateToHome()` | 快捷方法 | `navController.navigateToHome()` |
|
||
| `NavController.navigateSafe()` | 安全导航 | `navController.navigateSafe(route)` |
|
||
| `NavigationHelper` | 助手类 | `navigationHelper.handleBackPressed()` |
|
||
|
||
---
|
||
|
||
## 🚀 立即开始
|
||
|
||
### 第 1 步:查看示例
|
||
👉 打开 `NavigationExample.kt`,查看各种使用场景
|
||
|
||
### 第 2 步:阅读文档
|
||
👉 阅读 `ADVANCED_NAVIGATION.md`,了解详细内容
|
||
|
||
### 第 3 步:在项目中使用
|
||
👉 在您的代码中使用新的 Navigation API
|
||
|
||
### 第 4 步:参考最佳实践
|
||
👉 遵循文档中的最佳实践指南
|
||
|
||
---
|
||
|
||
## 📊 版本信息
|
||
|
||
| 项 | 信息 |
|
||
|----|------|
|
||
| 版本 | 2.0.0 (Navigation 高级版) |
|
||
| 发布日期 | 2026-01-19 |
|
||
| 状态 | ✅ 完成 |
|
||
| 兼容性 | Android 7.0+ |
|
||
|
||
---
|
||
|
||
## ✅ 检查清单
|
||
|
||
- [x] 核心类实现
|
||
- [x] 扩展方法实现
|
||
- [x] 示例代码完整
|
||
- [x] 文档详细完整
|
||
- [x] 异常处理完善
|
||
- [x] 测试用例示例
|
||
- [x] 最佳实践文档
|
||
- [x] 项目整合完成
|
||
|
||
---
|
||
|
||
## 📞 快速查询
|
||
|
||
**问题**: 如何快速导航?
|
||
**答**: 使用 `navController.navigateToHome()` 或 `navController.navigateToSettings()`
|
||
|
||
**问题**: 如何防止快速点击导致多次导航?
|
||
**答**: 使用 `navController.navigateSafe(route)`
|
||
|
||
**问题**: 如何在 ViewModel 中管理导航?
|
||
**答**: 使用 `NavigationEvent` 密封类和 LiveData
|
||
|
||
**问题**: 如何清理 Back Stack?
|
||
**答**: 使用 `navController.navigateAndClear(route, popUpTo)`
|
||
|
||
**问题**: 完整示例在哪里?
|
||
**答**: 查看 `NavigationExample.kt` 文件
|
||
|
||
---
|
||
|
||
**现在就开始使用新的 Navigation API 吧!** 🎉
|
||
|
||
更新日期: 2026-01-19
|
||
文档版本: 1.0
|