[Flutter学徒] 8 - 深链接&网页URL

2,098 阅读22分钟

本文由 简悦SimpRead 转码,原文地址 www.raywenderlich.com

了解如何建立一个Flutter应用程序,以处理移动和Web应用程序的深度链接。

有时,打开你的应用程序并通过导航来获得一个屏幕,对用户来说实在是太麻烦了。重定向到您的应用程序的特定部分是一个强大的营销工具,以促进用户参与。例如,为一个促销活动生成一个特殊的二维码,然后让用户扫描二维码访问你的应用程序中的特定产品,这是一个很酷很有效的方法来建立对产品的兴趣。

在上一章中,你学会了如何使用Navigator 2.0,用路由器小部件在屏幕之间移动,以声明的方式导航你的应用程序。现在,你将学习使用Navigator 2.0的更多功能。具体来说,你将学习如何在你的应用程序中深度链接到屏幕,并在网络上处理网络URL。

例如,以下是Fooderlich在Chrome网络浏览器中的样子。

在本章结束时,你将知道如何。

  • 解析URL字符串和查询参数。
  • 将URL转换为你的应用状态。
  • 在iOS和Android上支持深度链接。
  • 在浏览器中为Flutter网络应用支持URL驱动的导航。

本章将向您展示如何在三个平台上支持深度链接:iOS、Android和Web。你将能够引导用户到你所选择的任何屏幕。

注意。你需要安装Chrome网页浏览器来查看Fooderlich到网页。如果你还没有Chrome浏览器,你可以从www.google.com/chrome/获得它。Flutter网络项目可以在其他浏览器上运行,但本章只涉及在Chrome上的测试和开发。

了解深层链接

一个深层链接是一个URL,可以导航到你的移动应用中的一个特定目的地。你可以把深度链接想象成你在网络浏览器中输入的URL地址,以进入网站的特定页面而不是主页。

深度链接有助于用户参与和商业营销。例如,如果你正在进行销售,你可以将用户引导到你的应用程序中的特定产品页面,而不是让他们四处搜索。

想象一下,Fooderlich有自己的网站。当用户浏览该网站时,他们发现了一个他们想做的菜谱。通过使用深度链接,你可以让用户点击菜谱,直接在杂货店项目屏幕上打开应用程序,并立即开始向他们的购物清单添加原料。这为他们节省了时间,并使应用程序更加令人愉快。

  • 有了深度链接,Fooderlich更加自动化。它将用户直接带到物品的屏幕上,使其更容易创建一个新的物品。
  • 没有深层链接,它就更加手动。用户必须启动应用程序,浏览到购买标签,并点击**+**按钮,然后才能创建一个项目。这需要三个步骤,而不是一个步骤,而且很可能还需要一些头疼的问题!

深度链接的类型

有三种类型的深度链接。

  • URI方案。一个应用程序自己的URI方案。fooderlich://raywenderlich.com/home是Fooderlich的URI方案的一个例子。这种形式的深层链接只有在用户安装了你的应用程序后才能发挥作用。
  • iOS通用链接。在你的网络域名的根部,你放置一个指向特定应用ID的文件,以知道是否打开你的应用或引导用户到App Store。你必须向苹果公司注册该特定的应用程序ID,以处理来自该域的链接。
  • Android应用程序链接。这些就像iOS通用链接,但为Android平台。安卓应用链接将用户直接带到你的应用中的一个链接的具体内容。它们利用HTTP URLs并与一个网站相关联。对于没有安装你的应用程序的用户,这些链接将直接进入你的网站内容。

在本章中,你将只看URI计划。关于如何设置iOS通用链接和Android应用链接的更多信息,请查看以下内容。

开始使用

注意。我们建议你使用本章的启动项目,而不是继续使用上一章的项目。

在Android Studio中打开启动项目,运行flutter pub get。然后,在iOS或Android上运行该应用程序。

你会看到,Fooderlich的应用程序显示了登录界面。

很快,你就可以将用户重定向到应用程序的不同部分。但首先,花点时间回顾一下自上一章以来启动项目中的变化。

项目文件

在你深入研究解析URL之前,先看看这个启动项目中的新文件。

Screens文件夹

lib/screens/ 中有一个变化。

  • profile_screen.dart。处理用户打开 raywenderlich.com 时的两种不同情况。
    • 如果用户在手机上,它会在网页视图中打开网站。
    • 如果用户使用的是网络浏览器,它会在不同的标签中打开网站。

模型文件夹

lib/models/ 中有两个新增加的内容。

  • app_cache.dart。有助于缓存用户信息,如用户的登录和入职状态。它检查缓存,看用户是否需要登录或完成入职过程。
  • app_state_manager.dart: 依赖于AppCache来检查用户的登录和入职状态。当应用程序调用initializeApp()时,它检查应用程序缓存以更新相应的状态。

新包

pubspec.yaml 中,有两个新包。

url_launcher。^6.0.4
shared_preferences: ^2.0.5

下面是它们各自的作用。

  • url_launcher。一个跨平台的库,帮助启动一个URL。
  • shared_preferences: 包裹了平台特定的持久化存储的简单数据。AppCache使用这个包来存储用户登录和入职的状态。

新的Flutter网络项目

启动项目包括一个预建的Flutter web项目。

注意。为了加快进度,Web项目已经在您的启动项目中预先建立了。要学习如何创建一个Flutter网络应用,请查看。flutter.dev/docs/get-st…

设置深度链接

为了在iOS和Android上启用深度链接,你必须在各自的平台上添加一些元数据标签。

在iOS上设置深度链接

打开ios/Runner/Info.plist。你会看到一些新的键值对,这些键值对可以在iOS上实现深度链接。

<key>FlutterDeepLinkingEnabled</key>
<true/>
<key>CFBundleURLTypes</key>
<array>
  <dict>
  <key>CFBundleTypeRole</key>
  <string>Editor</string>
  <key>CFBundleURLName</key>
  <string>raywenderlich.com</string>
  <key>CFBundleURLSchemes</key>
  <array>
  <string>fooderlich</string>
  </array>
  </dict>
</array>

CFBundleURLName是一个独特的URL,可以将你的应用程序与其他使用相同方案的应用程序区分开来。fooderlich是你以后要使用的URL方案的名称。

在Android上设置深度链接

打开android/app/src/main/AndroidManifest.xml。在这里你还会发现<data>标签中的两个新定义。

<!-- Deep linking -->
<meta-data android: />
<intent-filter>
<action android: />
<category android: />
<category android: />
<data
  android:scheme="fooderlich"
  android:host="raywenderlich.com" />
</intent-filter>

像iOS一样,你为schemehost设置相同的值。

当你为Fooderlich创建一个深度链接时,自定义URL方案看起来像这样。

fooderlich://raywenderlich.com/<path>

现在,快速浏览一下你将创建的URL路径。

Fooderlich的路径概述

当涉及到你可以深度链接到Fooderlich的哪个屏幕时,你有很多选择。以下是你可以将你的用户重定向到的所有可能的路径。

路径:/

该应用初始化并检查应用缓存,看用户是否已登录并完成了入职指南。

  • /login。如果用户还没有登录,则重定向到登录界面。
  • /onboarding: 如果用户还没有完成入职培训,则重定向到入职培训屏幕。

路径:/home?tab=[index]

/home路径只有在用户已经登录并完成入职培训的情况下才会重定向到主屏幕。它包含一个查询参数,tab,它指向一个标签索引。如下面的截图所示,标签索引分别为012

路径:/profile

如果用户已经登录并完成了入职培训,/profile将重定向到个人资料界面。

路径:/item?id=[uuid]

/item将重定向到杂货店项目屏幕。它包含一个查询参数,id。有两种情况。

  1. 如果查询参数id有一个值,它将重定向到列表中的一个特定项目。
  2. 如果没有查询参数,它会显示一个空的项目屏幕,让用户创建一个新的项目。

你可以在下面中间的截图中看到这个结果。

注意。请记住,这些URL路径对移动和网络应用都是一样的。

当你在手机上做深层链接时,你将使用以下URI方案。

fooderlich://raywenderlich.com/<path>。

在网络上,URI方案与任何网络浏览器的URL一样。

http://localhost:60738/#/<path>

在你开始实施深度链接之前,花点时间快速回顾一下Navigator 2.0。

回顾Navigator 2.0

在上一章中,你学会了如何设置四个组件。RouterDelegate, Router, NavigatorBackButtonDispatcher

  • RouterDelegate的职责包括。
    • 使用App State来建立和配置页面列表。
    • 当应用程序首次启动时,检索并设置初始路由。
    • 当你显示一个新的路由时监听新的意图。
    • 监听操作系统提出的弹出路由的请求,通过。BackButtonDispatcher.
  • Router是一个扩展了RouterDelegate的小部件。路由器确保消息被传递给RouterDelegate
  • Navigator以声明的方式定义了一个MaterialPage'的堆栈。它也处理任何onPopPage'事件。
  • BackButtonDispatcher处理特定平台的系统后退按钮的按下。它监听操作系统的请求,并通知路由器代表弹出一个路由。

接下来你要看的两个组件是 路由信息提供器(RouteInformationProvider)路由信息解析器(RouteInformationParser)

  • RouteInformationProvider。向路由器提供路由信息。它通知路由器最初的路由,并将新的意图通知路由器。你不需要创建这个类,默认的实现通常就是你所需要的。
  • RouteInformationParser。从RouteInformationProvider获取路由字符串,然后将URL字符串解析为一个通用的用户定义的数据类型。这个数据类型是一个导航配置。

引擎盖下的深度链接

为了使深度链接工作,你需要做两件关键的事情:将URL转换为应用状态,并将应用状态转换为URL。接下来,你会看到这两件事的细节。

将一个URL转换为一个应用程序状态

支持深度链接的第一部分是弄清楚应用程序的哪个状态对应于一个特定的URL。下面是转换的过程。

  1. 用户输入一个由深度链接触发的新URL,或者通过改变网页浏览器地址栏中的URL。
  2. RouteInformationParser中,parseRouteInformation()将URL字符串转换为用户定义的数据类型。这被称为导航状态。这个数据类型包括路径和查询参数。你很快就会建立这个。
  3. 路由器然后调用setNewRoutePath(),将你的导航状态转换为应用状态。然后它将使用当前的应用状态来配置导航器栈。

将应用状态转换为URL字符串

当用户点击一个按钮或应用状态发生变化时,你需要改变当前的URL。下面是你设置你的应用程序处理URL时发生的情况。

  1. 路由器调用routerDelegatenotifyListeners(),让Flutter知道它需要更新当前URL。
  2. 它使用currentConfiguration()将你的应用状态转换回导航状态。
  3. restoreRouteInformation()然后将您的导航状态转换为URL字符串。在Flutter网络应用中,这将更新URL栏的地址。

注意。正如你所记得的,导航状态只是一个用户定义的数据类型。它将一个URL字符串转换为一个适当的数据类型。这个对象持有关于你的导航的信息,包括。

  • URL的路径或位置。
  • 查询参数。

在下一节中,AppLink是封装URL字符串的数据类型。

理论够了,是时候开始了

创建一个导航状态对象

AppLink是URL字符串和你的应用程序状态之间的中介对象。这个类的目的是解析导航配置与URL字符串的关系。

lib/navigation中,创建一个名为app_link.dart的新文件并添加以下内容。

class AppLink {
  // 1
  static const String kHomePath = '/home';
  static const String kOnboardingPath = '/onboarding';
  static const String kLoginPath = '/login';
  static const String kProfilePath = '/profile';
  static const String kItemPath = '/item';
	// 2
  static const String kTabParam = 'tab';
  static const String kIdParam = 'id';
	// 3
  String location;
  // 4
  int currentTab;
  // 5
  String itemId;
  // 6
  AppLink({this.location, this.currentTab, this.itemId});

  // TODO: Add fromLocation

  // TODO: Add toLocation
}

AppLink是你的导航状态对象。花点时间来理解你添加的属性。在上面的代码中,你。

  1. 为每个URL路径创建常量。
  2. 为你将支持的每个查询参数创建常量。
  3. 使用location存储URL的路径。
  4. 使用currentTab来存储你想重定向给用户的标签。
  5. itemId中存储你想查看的项目的ID。
  6. 用位置和两个查询参数初始化应用程序链接。

将一个URL字符串转换成一个AppLink

AppLink是一个帮助存储路径信息的对象。它帮助解析URL字符串到路由,反之亦然,将路由信息转换回URL字符串。它本质上封装了所有将简单的字符串转换为状态并返回的逻辑。

接下来找到// TODO: 添加fromLocation并添加以下内容。

static AppLink fromLocation(String location) {
  // 1
  location = Uri.decodeFull(location);
  // 2
  final uri = Uri.parse(location);
  final params = uri.queryParameters;
  // 3
  void trySet(String key, void Function(String) setter) {
    if (params.containsKey(key)) setter?.call(params[key]);
  }
  // 4
  final link = AppLink()..location = uri.path;
  // 5
  trySet(AppLink.kTabParam, (s) => link.currentTab = int.tryParse(s));
  trySet(AppLink.kIdParam, (s) => link.itemId = s);
  // 6
  return link;
}

fromLocation()将一个URL字符串转换为一个AppLink

  1. 首先,你需要对URL进行解码。URL的路径中经常包含特殊字符,所以你需要对URL路径进行**%的编码。例如,你要把hello!world编码为hello%21world
  2. 解析URI的查询参数键和键值对。
  3. trySet()是一个内部函数,如果值不是空的,就会注入键。
  4. 用当前路径创建`AppLink'。
  5. 注入你在URL中发现的查询参数。
  6. 返回AppLink的实例。

将AppLink转换为URL字符串

该应用程序还需要进行相反的转换,从AppLink到简单的字符串。

找到// TODO: Add toLocation并添加以下内容。

String toLocation() {
  // 1
  String addKeyValPair({String key, String value}) =>
      value == null ? '' : '${key}=$value&';
	// 2
  switch (location) {
    // 3
    case kLoginPath:
     return kLoginPath;
    // 4
    case kOnboardingPath:
      return kOnboardingPath;
    // 5
    case kProfilePath:
      return kProfilePath;
    // 6
    case kItemPath:
      var loc = '$kItemPath?';
      loc += addKeyValPair(key: kIdParam, value: itemId);
      return Uri.encodeFull(loc);
    // 7
    default:
      var loc = '$kHomePath?';
      loc += addKeyValPair(key: kTabParam, value: currentTab.toString());
      return Uri.encodeFull(loc);
  }
}

这将AppLink转换为URI字符串。下面是它的工作原理。你。

  1. 创建一个内部函数,将查询参数的键值对转换成字符串格式。

  2. 遍历每个定义的路径。

  3. 如果路径是kLoginPath,返回正确的字符串路径。/login

  4. 如果路径是kOnboardingPath,返回正确的字符串路径。/onboarding

  5. 如果路径是kProfilePath,返回正确的字符串路径。`/profile'。

  6. 如果路径是kItemPath,返回正确的字符串路径。/item,如果有任何参数,附加上?id=${id}

  7. 如果路径无效,默认为路径/home。如果用户选择了一个标签,附加?tab=${tabIndex}

接下来,你将使用RouteInformationParser来解析路由信息到AppLink

创建一个路线信息解析器

navigation目录下,创建一个名为app_route_parser.dart的新文件并添加以下内容。

import 'package:flutter/material.dart';
import 'app_link.dart';

// 1
class AppRouteParser extends RouteInformationParser<AppLink> {
  // 2
  @override
  Future<AppLink> parseRouteInformation(
      RouteInformation routeInformation) async {
    // 3
    final link = AppLink.fromLocation(routeInformation.location);
    return link;
  }

  // 4
  @override
  RouteInformation restoreRouteInformation(AppLink appLink) {
    // 5
    final location = appLink.toLocation();
    // 6
    return RouteInformation(location: location);
  }
}

以下是代码的工作方式。

  1. AppRouteParser扩展了RouteInformationParser。注意它需要一个通用类型。在这种情况下,你的类型是AppLink,它持有所有的路线和导航信息。
  2. 你需要覆盖的第一个方法是parseRouteInformation()。路线信息包含URL字符串。
  3. 取出路线信息,并从中建立一个AppLink的实例。
  4. 你需要覆盖的第二个方法是restoreRouteInformation()
  5. 这个函数传入一个AppLink'对象。你要求AppLink`给你回馈URL字符串。
  6. 你把它包在RouteInformation中来传递它。

将解析器连接到应用程序路由器上

现在你已经设置了你的RouteInformationParser,现在是时候把它连接到你的路由器委托。

打开lib/main.dart,找到// TODO: Initialize RouteInformationParser并将其改为以下内容。

final routeParser = AppRouteParser();

在这里,你初始化你的应用程序路由解析器。如果它没有自动导入,请确保在顶部添加以下内容。

import 'navigation/app_route_parser.dart';

接下来,找到// TODO。替换为Material.router,并将其下方的return语句替换为以下内容。

return MaterialApp.router(
  theme: theme,
  title: 'Fooderlich',
  backButtonDispatcher: RootBackButtonDispatcher(),
  // 1
  routeInformationParser: routeParser,
  // 2
  routerDelegate: _appRouter,
);

你已经创建了一个MaterialApp,初始化了一个内部路由器。下面是它的作用。

  1. 设置routeParser。记住,路由信息解析器的工作是将应用状态转换为URL字符串。
  2. routerDelegate帮助构建代表你的应用程序状态的页面堆栈。

在这一点上,你可能会在模拟器上看到一些错误。你很快就会修复它们。

将一个URL转换为一个应用程序状态

当用户在网页上输入一个新的URL或在移动端触发一个深度链接时,RouteInformationProvider会通知RouteInformationParser有一个新的路由,如下图所示。

以下是从URL到应用程序状态的过程。

  1. 用户在网页浏览器的地址栏中输入一个新的URL。
  2. RouteInformationParser将新的路线解析为你的导航状态,即AppLink的一个实例。
  3. 基于导航状态,RouterDelegate更新应用程序状态以反映新的变化。

配置导航

快速的理论测试。将一个特定的URL路径映射到一个特定的屏幕的逻辑在哪里?它在setNewRoutePath()中!

打开lib/navigation/app_router.dart,找到// TODO: 添加<AppLink>,用以下内容替换它和它前面的空格。

<AppLink>

记住,AppLink封装了所有的路由信息。上面的代码将RouterDelegate的用户定义的数据类型设置为AppLink

如果在顶部还没有添加导入,请添加以下内容。

import 'app_link.dart';

接下来,找到// TODO: 替换setNewRoutePath,用下面的注释和代码替换。

// 1
@override
Future<void> setNewRoutePath(AppLink newLink) async {
  // 2
  switch (newLink.location) {
    // 3
    case AppLink.kProfilePath:
      profileManager.tapOnProfile(true);
      break;
    // 4
    case AppLink.kItemPath:
      // 5
      if (newLink.itemId != null) {
        groceryManager.setSelectedGroceryItem(newLink.itemId);
      } else {
        // 6
        groceryManager.createNewItem();
      }
      // 7
      profileManager.tapOnProfile(false);
      break;
    // 8
    case AppLink.kHomePath:
      // 9
      appStateManager.goToTab(newLink.currentTab ?? 0);
      // 10
      profileManager.tapOnProfile(false);
      groceryManager.groceryItemTapped(null);
      break;
    // 11
    default:
      break;
  }
}

下面是你如何将你的应用链接转换为应用状态。

  1. 当一个新的路由被推送时,你调用setNewRoutePath()。它传递了一个`AppLink'。这是你的导航配置。
  2. 使用一个`开关'来检查每个位置。
  3. 如果新的位置是/profile,显示Profile屏幕。
  4. 检查新的位置是否以/item开头。
  5. 如果itemId不是空的,设置所选的杂货项目并显示杂货项目屏幕。
  6. 如果itemId是空的,显示一个空的杂货项目屏幕。
  7. 隐藏简介屏幕。
  8. 如果新的位置是/home
  9. 设置当前选择的标签。
  10. 确保个人资料屏幕和杂货店项目屏幕被隐藏。
  11. 如果位置不存在,什么都不要做。

将应用程序的状态转换为一个URL

在这一点上,你已经将一个URL转换为一个应用程序状态。接下来,你需要做相反的事情。当用户点击一个按钮或导航到另一个屏幕时,你需要将应用状态转换回一个URL字符串。对于网络应用,这将同步浏览器的地址栏。

  1. 当用户按下一个按钮或修改一个状态时,notifyListeners()就会启动。
  2. RouteInformationParser要求提供当前的导航配置,所以你必须将你的应用状态转换为AppLink
  3. RouteInformationParser然后调用restoreRouteInformation并将AppLink转换为一个URL字符串。

还是在lib/navigation/app_router.dart中,找到//TODO: Convert app state to applink,然后用下面的内容替换它。

AppLink getCurrentPath() {
  // 1
  if (!appStateManager.isLoggedIn) {
    return AppLink(location: AppLink.kLoginPath);
  // 2
  } else if (!appStateManager.isOnboardingComplete) {
    return AppLink(location: AppLink.kOnboardingPath);
  // 3
  } else if (profileManager.didSelectUser) {
    return AppLink(location: AppLink.kProfilePath);
  // 4
  } else if (groceryManager.isCreatingNewItem) {
    return AppLink(location: AppLink.kItemPath);
  // 5
  } else if (groceryManager.selectedGroceryItem != null) {
    final id = groceryManager.selectedGroceryItem.id;
    return AppLink(location: AppLink.kItemPath, itemId: id);
  // 6
  } else {
    return AppLink(
        location: AppLink.kHomePath,
        currentTab: appStateManager.getSelectedTab);
  }
}

这是一个辅助函数,将应用状态转换为AppLink对象。下面是它的工作原理。

  1. 如果用户还没有登录,返回带有登录路径的应用程序链接。
  2. 如果用户还没有完成入职培训,返回带有入职培训路径的应用程序链接。
  3. 如果用户点击了个人资料,返回带有个人资料路径的应用程序链接。
  4. 如果用户点击 + 按钮来创建一个新的杂货店项目,返回带有项目路径的应用链接。
  5. 如果用户选择了一个现有的项目,返回一个带有项目路径和项目`id'的应用链接。
  6. 如果没有一个条件被满足,默认返回带有所选标签的主路径。

接下来,找到// TODO: Apply configuration helper并将其替换为以下内容。

@override
AppLink get currentConfiguration => getCurrentPath();

访问currentConfiguration会调用帮助器getCurrentPath(),它检查应用状态并返回正确的应用链接配置。

恭喜你,你现在已经设置好了一切 现在,你可以看到你的工作在行动。

测试深度链接

下一步,你将测试深度链接在iOS、Android和网络上的工作情况。

在iOS上测试深度链接

在Android Studio中,选择一个iOS设备并按下播放按钮。

一旦模拟器运行,登录并完成上机,如下图所示。

深度链接到主屏幕

在你的终端输入以下内容。

xcrun simctl openurl booted 'fooderlich://raywenderlich.com/home?tab=1'

在模拟器中,这会自动切换到Fooderlich的第二个标签,如下所示。

深度链接到简介屏幕

接下来,运行以下命令。

xcrun simctl openurl booted 'fooderlich://raywenderlich.com/profile'

这将打开配置文件屏幕,如下图所示。

深度链接创建一个新项目

接下来,运行以下命令。

xcrun simctl openurl booted 'fooderlich://raywenderlich.com/item'

现在杂货店项目屏幕将显示。

按照这个模式,你可以在你的应用程序中建立通往任何位置的路径!

在iOS模拟器中重新设置缓存

回想一下,AppStateManagerAppCache一起检查,看用户是否登录或已经上机。如果你想重置缓存以再次看到登录界面,你有两个选择。

  1. 进入个人资料视图,点击注销。这将使应用程序的缓存失效。

  1. 如果你在iOS模拟器上运行,你可以选择**擦除所有内容和设置...**来清除缓存。

注意。你在模拟器上的任何其他应用程序也将被删除。

在Android上测试深度链接

停止在iOS上运行。打开Android Studio,选择一个Android设备并点击播放按钮。

一旦模拟器或设备运行,登录并完成上机过程,如下图所示。

深度链接到主屏幕

在你的终端输入以下内容。

~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE
    -d 'fooderlich://raywenderlich.com/home?tab=1'

注意。如果你在终端机中收到类似的信息。Warning: 活动未启动,意图已交付给当前运行的最顶层实例,请忽略它。这只意味着该应用程序已经在运行。

列出完整的路径是为了确保如果你的$PATH中没有adb,你仍然可以执行这个命令。每行末尾的\是为了很好地格式化多行的脚本。

这个命令指向Fooderlich的第二个标签,如下所示。

深度链接到简介屏幕

接下来,运行以下命令。

~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE
    -d 'fooderlich://raywenderlich.com/profile'

这就打开了个人资料屏幕,如下图所示。

深度链接到创建新项目

接下来,运行以下命令。

~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE
    -d 'fooderlich://raywenderlich.com/item'

Grocery Item屏幕将出现,如下图所示。

重置安卓系统中的缓存

如果你需要重置你的用户缓存,这里是你要做的。

  1. 长按Fooderlich应用图标,然后点击应用信息
  2. 接下来,点击存储和缓存
  3. 最后,点击清除缓存。这将清除你的缓存。

现在,是时候测试Fooderlich如何处理网络上的URL。

运行网络应用程序

停止在Android上运行。在Android Studio中,选择Chrome (web)并点击Play按钮。

注意。你的数据不会在应用启动之间持续存在。这是因为Flutter web在开发过程中运行的是相当于隐身模式。

如果您构建并发布您的Flutter网络应用,它将按预期工作。关于如何构建发布的更多信息,请查看。flutter.dev/docs/deploy…

通过Fooderlich UI流程,你会看到网页浏览器的地址栏发生了变化。

如果你把tab查询参数的值改为012,应用程序将自动切换到该标签。

接下来,请注意,点击 + 按钮可以打开杂货店的项目。

需要注意的一件很酷的事情是,该应用程序存储了整个浏览器的历史记录。

点击返回前进按钮,该应用程序将恢复该状态! 这有多酷啊?你可以做的另一件事是长按返回按钮,跳到浏览器历史中的一个特定状态。

恭喜您学会了如何在您的Flutter应用程序中使用深层链接!

关键点

  • 当有新的路线时,应用程序会通知RouteInformationProvider
  • 提供者将路由信息传递给RouteInformationParser以解析URL字符串。
  • 该解析器将应用状态转换为URL字符串,并从URL字符串中转换。
  • AppLink为导航状态建模。它是一个用户定义的数据类型,封装了关于URL字符串的信息。
  • 在开发模式下,Flutter网络应用程序在应用启动之间不会持久化数据。在发布模式下生成的Web应用程序将在其他浏览器上工作。

何去何从?

如果您对如何在web应用中删除URL中的#符号感到好奇,请查看。flutter.dev/docs/develo…

看看gSkinner的flutter-folio应用如何处理导航。应用程序链接的想法来自于这个示例项目。在这里看看他们的例子。github.com/gskinnerTea…

你可以在这里看到两种不同类型的网络渲染器的例子。flutter.dev/docs/develo…

你学会了如何扩展Navigator 2.0以支持深度链接和同步网络浏览器的URL地址栏。这有助于将用户带到你的应用程序中的特定目的地,建立更好的用户参与度

能够为多个平台管理你的导航状态,确实令人惊奇!


www.deepl.com 翻译