🚇 Android 导航大冒险:Navigation 组件的地铁系统指南

60 阅读3分钟

​故事背景​​:你的 App 是一座超级城市,每个 Fragment 是一个地铁站点,Navigation 就是城市地铁系统。NavController 是列车司机,NavGraph 是地铁线路图,而 NavHost 就是容纳列车的地铁站台!


🗺️ 第一章:建造地铁系统 - 基础配置

1. 创建地铁总站(NavHost)

xml
Copy
<!-- activity_main.xml -->
<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host"
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:defaultNavHost="true" <!-- 设为默认总站 -->
    app:navGraph="@navigation/city_subway" /> <!-- 导入地铁线路图 -->

2. 绘制地铁线路图(NavGraph)

xml
Copy
<!-- res/navigation/city_subway.xml -->
<navigation 
    android:id="@+id/city_subway"
    app:startDestination="@id/home_station"> <!-- 始发站 -->

    <!-- 站点声明 -->
    <fragment
        android:id="@+id/home_station"
        android:name="com.example.HomeFragment"
        android:label="首页">
        
        <!-- 轨道连接 -->
        <action
            android:id="@+id/to_profile"
            app:destination="@id/profile_station" />
    </fragment>

    <fragment
        android:id="@+id/profile_station"
        android:name="com.example.ProfileFragment"
        android:label="个人中心">
        
        <!-- 返程轨道 -->
        <action 
            android:id="@+id/back_home"
            app:popUpTo="@id/home_station" 
            app:popUpToInclusive="true" />
    </fragment>
</navigation>

🚄 第二章:列车运行 - 导航操作

1. 启动列车(导航跳转)

kotlin
Copy
// 在 HomeFragment.kt 中
fun goToProfile() {
    // 获取列车司机 (NavController)
    val navController = findNavController()
    
    // 发车指令!沿 "to_profile" 轨道行驶
    navController.navigate(R.id.to_profile)
}

2. 特快列车(带参数传递)

xml
Copy
<!-- 在 city_subway.xml 中声明参数轨道 -->
<fragment android:id="@+id/profile_station"...>
    <argument
        android:name="user_id"
        app:argType="string" />
</fragment>
kotlin
Copy
// 传递用户ID车票
fun goToProfile(user: User) {
    val bundle = bundleOf("user_id" to user.id)
    navController.navigate(R.id.to_profile, bundle)
}

// 在 ProfileFragment 中取票
val userId = arguments?.getString("user_id") 

3. 返程列车(退回上一站)

kotlin
Copy
// 在 ProfileFragment 中
fun goBack() {
    // 方法1:自动返回(使用系统返回键逻辑)
    navController.navigateUp()
    
    // 方法2:指定返回 Home 站
    navController.popBackStack(R.id.home_station, false)
}

🎢 第三章:高级调度 - 动画与深度链接

1. 轨道特效(转场动画)

xml
Copy
<!-- 在 action 中添加动画轨道 -->
<action 
    android:id="@+id/to_profile"
    app:destination="@id/profile_station"
    app:enterAnim="@anim/slide_in_right"  <!-- 进站动画 -->
    app:exitAnim="@anim/slide_out_left"   <!-- 离站动画 -->
    app:popEnterAnim="@anim/slide_in_left" <!-- 返程进站 -->
    app:popExitAnim="@anim/slide_out_right"/> <!-- 返程离站 -->

2. 秘密通道(深度链接)

xml
Copy
<!-- 在 profile_station 添加秘密入口 -->
<deepLink app:uri="myapp://profile/{user_id}" />

<!-- AndroidManifest.xml 中声明 -->
<activity ...>
    <nav-graph android:value="@navigation/city_subway" />
</activity>
kotlin
Copy
// 通过网页唤醒特快列车
val request = NavDeepLinkRequest.Builder
    .fromUri("myapp://profile/user123".toUri())
    .build()

findNavController().navigate(request) // 直达Profile站!

🚦 第四章:列车控制系统 - 高级技巧

1. 多线路管理(嵌套导航图)

xml
Copy
<!-- 创建购物区子线路图 -->
<navigation 
    android:id="@+id/mall_area"
    app:startDestination="@id/shop_station">
    
    <fragment android:id="@+id/shop_station".../>
    <fragment android:id="@+id/cart_station".../>
</navigation>

<!-- 在主图中添加入口 -->
<include app:graph="@navigation/mall_area" />

<!-- 跳转到子图入口站 -->
findNavController().navigate(R.id.mall_area)

2. 列车广播系统(ViewModel 共享)

kotlin
Copy
// 在 MainActivity 中创建共享 ViewModel
val viewModel: SharedViewModel by viewModels()

// 所有 Fragment 通过同一 NavController 获取
class HomeFragment : Fragment() {
    private val model by navGraphViewModels<SharedViewModel>(R.id.city_subway)
    
    fun updateData() {
        model.liveData.value = "最新城市新闻!"
    }
}

3. 危险路段防护(安全参数)

kotlin
Copy
// 添加安全插件
plugins {
    id("androidx.navigation.safeargs.kotlin")
}

// 生成参数类
fun goToProfile(user: User) {
    // 类型安全的导航!
    val direction = HomeFragmentDirections.toProfile(userId = user.id)
    navController.navigate(direction)
}

// ProfileFragment 中安全获取
private val args: ProfileFragmentArgs by navArgs()
val userId = args.userId // 自动处理空安全!

🚧 第五章:故障排除 - 地铁管理局指南

故障现象解决方案
​列车卡在隧道中​检查 popUpTo 是否设置正确
​车票(参数)丢失​使用 Safe Args 插件保障类型安全
​列车开错方向​确认 action 的 destination 是否正确
​秘密通道无法通行​检查 AndroidManifest 深度链接配置
​转场动画失灵​确保动画资源文件存在且无兼容问题

​站长备忘录​​:

  1. 使用 ​​Navigation Editor​​ 可视化设计线路图(Android Studio 右键 res/navigation)
  2. 用 FragmentScenario 测试导航流程(模拟列车运行)
  3. 使用 ​​Navigation AdvancedSample​​ 学习复杂案例

现在,拿起你的地铁控制台(NavController),启动高效的城市交通系统吧!记住:​​清晰的线路图(NavGraph)是避免乘客(用户)迷路的关键!​​ 🚇✨