# Flutter Navigator 進階應用 - 深層鏈接&網頁URL 在前一篇[Navigator介紹](https://hackmd.io/lxmLX9h6TCCnOFMBfAwaGg?view)用路由器小部件在頁面之間移動,以聲明的方式導航你的APP。 那當我們希望**可以透過網址來到達指定頁面**,例如:為一個促銷活動生成一個特殊的二維碼,然後讓用戶掃描二維碼訪問你的應用程序中的特定產品,而Navigator 2.0也提供了這類功能。 ## Deep Link 深層鏈接 深層鏈接是一個URL,可以導航到你的APP中的一個特定目的地。你可以把深度鏈接想像成你在網絡瀏覽器中輸入的URL地址,**可以直接進入網站的特定頁面而不是主頁。** ## 調整設定檔 ### IOS ios/Runner/Info.plist ```xml <key>FlutterDeepLinkingEnabled</key> <true/> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLName</key> <string>yenyen.com</string> <key>CFBundleURLSchemes</key> <array> <string>fooderlich</string> </array> </dict> </array> ``` ![](https://i.imgur.com/5X5zRP9.png) ### Android ```xml <!-- Deep linking --> <meta-data android:name="flutter_deeplinking_enabled" android:value="true" /> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="fooderlich" android:host="yenyen.com" /> </intent-filter> ``` ![](https://i.imgur.com/g4rVxi4.png) > 注意事項: android:scheme="fooderlich" android:host="yenyen.com" 輸入adb指令時記得要跟設定檔相符,後續內容也會有相關Demo ## 程式範例 ### 主程式 main.dart ```dart class _FooderlichState extends State<Fooderlich> { //略... final _appStateManager = AppStateManager(); //提供的路由設定管理pages的內容 final routeParser = AppRouteParser(); //將路由資訊解析成自定義的路由設定類別 late AppRouter _appRouter; @override void initState() { super.initState(); //給予初始值 _appRouter = AppRouter( appStateManager: _appStateManager, //略 ); } @override Widget build(BuildContext context) { return MultiProvider( providers: [ ChangeNotifierProvider( create: (context) => _appStateManager, ), ], child: return MaterialApp.router( theme: theme, title: 'Fooderlich', routeInformationParser: routeParser, routerDelegate: _appRouter, ); ); } } ``` #### 參考資料 https://ithelp.ithome.com.tw/m/articles/10263763 ### routeInformationParser 將路由資訊解析成自定義的路由設定類別, #### navigation/app_route.dart ```dart import 'app_link.dart'; class AppRouteParser extends RouteInformationParser<AppLink> { @override Future<AppLink> parseRouteInformation( RouteInformation routeInformation) async { final link = AppLink.fromLocation(routeInformation.location); return link; } @override RouteInformation restoreRouteInformation(AppLink appLink) { return RouteInformation(location: appLink.toLocation()); } } ``` #### navigation/app_link.dart 將收到的data進行解析 ```dart class AppLink { static const String homePath = '/home'; static const String onboardingPath = '/onboarding'; static const String loginPath = '/login'; static const String profilePath = '/profile'; static const String itemPath = '/item'; static const String tabParam = 'tab'; static const String idParam = 'id'; String? location; int? currentTab; String? itemId; AppLink({ this.location, this.currentTab, this.itemId, }); static AppLink fromLocation(String? location) { location = Uri.decodeFull(location ?? ''); final uri = Uri.parse(location); final params = uri.queryParameters; final currentTab = int.tryParse(params[AppLink.tabParam] ?? ''); final itemId = params[AppLink.idParam]; final link = AppLink( location: uri.path, currentTab: currentTab, itemId: itemId, ); return link; } String toLocation() { String addKeyValPair({ required String key, String? value, }) => value == null ? '' : '$key=$value&'; switch (location) { case loginPath: return loginPath; case onboardingPath: return onboardingPath; case profilePath: return profilePath; case itemPath: String loc = '$itemPath?'; loc += addKeyValPair( key: idParam, value: itemId, ); return Uri.encodeFull(loc); default: var loc = '$homePath?'; loc += addKeyValPair( key: tabParam, value: currentTab.toString(), ); return Uri.encodeFull(loc); } } } ``` ## adb測試 ### 跳轉到指定頁面 開啟控制台輸入 ```command adb shell am start -a android.intent.action.VIEW \ -c android.intent.category.BROWSABLE \ -d 'fooderlich://yenyen.com/home?tab=1' ``` * -s: 對特定機器下adb指令 * shell am start: 開啟或執行shell指令activity * -a: actiot * -c: category * -d: data ### 除錯 [Flutter - 疑難炸症](https://hackmd.io/@BzWzq-x9Rb2G4WG03gcyKg/HkQ-sePtc#adb%E7%9B%B8%E9%97%9C) ###### tags: `flutter`