移动/游戏
Flutter 应用需要 URL 路由…
在 Flutter 中(尤其 Web 或需深链接的移动端)配置基于 URL 的声明式路由、平台深链接与嵌套导航。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
Flutter 应用需要 URL 路由、通用
解决思路
- 创建应用并添加依赖:运行 `flutter create <app-name>`、`cd <app-name>`、`flutter pub add go_router`。
- 在 main() 中调用 `usePathUrlStrategy()`(来自 `package:flutter_web_plugins/url_strategy.dart`),去掉 Web URL 中的 `#` 片段,保证跨平台深链接干净。
- 定义顶层 `GoRouter` 实例:设置 `initialLocation`、`routes`(用 `GoRoute` 把路径映射到页面,子路由嵌套在 `routes` 内,如 `details/:id` 通过 `state.pathParameters['id']` 取参)、`errorBuilder` 处理错误页,并可用 `redirect` 处理鉴权或状态路由。
- 用 `MaterialApp.router(routerConfig: _router)` 把路由器绑定到应用根组件。
- 配置 Android 深链接:在 `AndroidManifest.xml` 的 `.MainActivity` 的 `<activity>` 内添加 `<intent-filter android:autoVerify="true">`,包含 VIEW action、DEFAULT/BROWSABLE category 及 http/https 的 `<data>` 域名;并在 `https://yourdomain.com/.well-known/assetlinks.json` 托管含 `delegate_permission/common.handle_all_urls`、`package_name`、`sha256_cert_fingerprints` 的 JSON。
- 配置 iOS 深链接:在 `Info.plist` 中设 `FlutterDeepLinkingEnabled` 为 `true`(若用第三方深链接插件如 `app_links` 则设为 `NO` 避免冲突);在 `Runner.entitlements` 添加 `com.apple.developer.associated-domains` 数组含 `applinks:yourdomain.com`;并在 `https://yourdomain.com/.well-known/apple-app-site-association`(无 .json 扩展名)托管含 `appIDs` 与 `paths` 的 JSON。
- 验证深链接:Android 用 `adb shell 'am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://yourdomain.com/details/123" com.yourcompany.yourapp'`;iOS 在已启动模拟器上用 `xcrun simctl openurl booted https://yourdomain.com/details/123`;根据报错修复配置。
- 实现嵌套导航:在 `GoRouter` 中用 `StatefulShellRoute.indexedStack`,其 `builder` 返回自定义 shell(如带底部导航栏的 Scaffold),并为每个标签页创建 `StatefulShellBranch` 包裹各自的 `GoRoute`,以保持各分支导航状态。
- 实现 shell 组件:接收 `StatefulNavigationShell`,用 `navigationShell` 作为 body、`navigationShell.currentIndex` 作为选中索引,在点击时调用 `navigationShell.goBranch(index, initialLocation: index == navigationShell.currentIndex)`(点击当前标签时回到该分支初始位置)。
- 程序化导航:用 `context.go('/details/123')` 替换当前路由栈(声明式)、`context.push('/details/123')` 压栈(命令式)、`context.goNamed('details', pathParameters: {'id': '123'})` 按命名路由带参导航、`context.pop()` 返回上一页。
适用边界 · 注意事项
- 不使用 go_router 或不需要 URL/深链接的简单应用,用内置 Navigator 即可。
- 未在服务端托管 assetlinks.json / apple-app-site-association 时,Android/iOS 的自动深链接验证不会生效。
- 使用第三方深链接插件时,iOS 的 FlutterDeepLinkingEnabled 必须设为 NO,否则会冲突。