Flutter深度链接插件flutter_deep_linking的使用

Flutter深度链接插件flutter_deep_linking的使用

通过适当的深度链接处理所有路由,并以声明方式处理它们!

这个包是关于什么的

这个包接收导航过程中传入的URI,评估定义好的路由并返回正确的页面对应的PageRoute。这意味着,你可以受益于松耦合的特性,并使用以下方式进行导航:

Navigator.of(context).pushNamed('/articles/$id')

而不是每次都硬编码相应的Widget:

Navigator.of(context)
  .push(MaterialPageRoute(builder: (_) => ArticlePage(id)));

这个包不是关于什么的

这个包不捕捉来自其他应用的深度链接。对于这一点,我推荐使用<kbd>uni_links</kbd>

然而,你可以将这两个包结合起来使用。只需将接收到的深度链接转发到你的Navigator,然后由flutter_deep_linking负责解析它们。这同样适用于初始的深度链接:

String initialLink = await getInitialLink(); // from uni_links
return MaterialApp(
  initialRoute: initialLink,
  onGenerateRoute: router.onGenerateRoute,   // from flutter_deep_linking
  // ...
);

开始使用

1. 创建包含所有路由的Router

final router = Router(
  routes: [
    Route(
      // 这个匹配任何指向schul-cloud.org的HTTP或HTTPS URI。
      // 由于`isOptional`为true,这也匹配没有scheme或domain的URI,但不匹配其他域名。
      matcher: Matcher.webHost('schul-cloud.org', isOptional: true),
      // 这些嵌套的路由只有在上面的条件匹配时才会被评估。
      routes: [
        Route(
          matcher: Matcher.path('courses'),
          materialBuilder: (_, __) => CoursesPage(),
          routes: [
            // 如果这个路由匹配,则使用它。否则,回退到外层的courses-route。
            Route(
              // {courseId}是一个参数,匹配一个路径段。
              matcher: Matcher.path('{courseId}'),
              materialBuilder: (_, RouteResult result) {
                // 你可以使用`result[<name>]`访问匹配的参数。
                return CourseDetailPage(result['courseId']);
              },
            ),
          ],
        ),
        Route(
          // Matcher.path也可以匹配嵌套路径。
          matcher: Matcher.path('user/settings'),
          materialBuilder: (_, __) => SettingsPage(),
        ),
      ],
    ),
    // 这个路由没有指定matcher,因此匹配任何路由。
    Route(
      materialBuilder: (_, RouteResult result) => NotFoundPage(result.uri),
    ),
  ],
);

注意: Flutter也定义了名为RouteRouteBuilder的类,这可能会引起混淆。如果你在同一文件中导入了package:flutter/widgets.dart,你可以在导入flutter_deep_linking时忽略Flutter的RouteRouteBuilder,方法是添加import 'package:flutter/widgets.dart' hide Route, RouteBuilder;

Router接受一系列Route,这些Route从上到下,深度优先进行搜索。使用Matcher可以匹配URI的一部分。内部Matcher不能访问已经被外部Matcher匹配的部分。

为了构建实际的页面,你可以指定以下之一:

  • <a href="https://pub.dev/documentation/flutter_deep_linking/latest/flutter_deep_linking/Route/builder.html"><code>Route.builder</code></a>:接受一个<a href="https://pub.dev/documentation/flutter_deep_linking/latest/flutter_deep_linking/RouteResult-class.html"><code>RouteResult</code></a>并返回一个Flutter的<a href="https://api.flutter.dev/flutter/widgets/Route-class.html"><code>Route</code></a>实例。
  • <a href="https://pub.dev/documentation/flutter_deep_linking/latest/flutter_deep_linking/Route/materialBuilder.html"><code>Route.materialBuilder</code></a>(便捷属性):接受一个<code>BuildContext</code>和一个<a href="https://pub.dev/documentation/flutter_deep_linking/latest/flutter_deep_linking/RouteResult-class.html"><code>RouteResult</code></a>并返回一个widget,然后将其包装在<a href="https://api.flutter.dev/flutter/material/MaterialPageRoute-class.html"><code>MaterialPageRoute</code></a>中。

2. 让你的RouterMaterialApp(或CupertinoApp或自定义的Navigator)中处理URI的解析

MaterialApp(
  onGenerateRoute: router.onGenerateRoute,
  // ...
)

更多关于Flutter深度链接插件flutter_deep_linking的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter深度链接插件flutter_deep_linking的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用flutter_deep_linking插件的示例代码案例。这个插件允许你处理深度链接(Deep Linking),使得用户可以通过点击链接直接跳转到应用内的特定页面。

首先,确保你已经在pubspec.yaml文件中添加了flutter_deep_linking依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_deep_linking: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来安装依赖。

1. 配置AndroidManifest.xml(Android)

在Android项目中,你需要配置AndroidManifest.xml以支持深度链接。例如,如果你想要处理example://这样的URL,你可以这样配置:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <application
        ...>
        
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <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="example" android:host="yourapp" />
            </intent-filter>
        </activity>
        
    </application>
</manifest>

2. 配置Info.plist(iOS)

在iOS项目中,你需要在Info.plist中添加URL Types配置。例如:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>example</string>
        </array>
    </dict>
</array>

3. 在Flutter代码中使用深度链接

接下来,在你的Flutter代码中初始化并使用flutter_deep_linking插件。以下是一个基本的示例:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Deep Linking Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/',
      routes: {
        '/': (context) => HomePage(),
        '/details': (context) => DetailsPage(),
      },
      onGenerateRoute: (settings) {
        // 在这里处理深度链接
        FlutterDeepLinking.initialLink(context).then((initialLink) {
          if (initialLink != null && initialLink.isNotEmpty) {
            // 根据链接导航到相应的页面
            if (initialLink == 'details') {
              Navigator.pushNamed(context, '/details');
            }
          }
        });
        return MaterialPageRoute(builder: (context) => HomePage());
      },
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 模拟打开深度链接
            Uri deepLink = Uri(scheme: 'example', host: 'yourapp', path: '/details');
            launch(deepLink.toString());
          },
          child: Text('Open Deep Link'),
        ),
      ),
    );
  }
}

class DetailsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Details Page'),
      ),
      body: Center(
        child: Text('You have reached the details page via deep linking!'),
      ),
    );
  }
}

在这个示例中,我们配置了一个简单的Flutter应用,其中有两个页面:HomePageDetailsPageFlutterDeepLinking.initialLink用于在应用启动时获取初始的深度链接,并根据链接导航到相应的页面。我们还提供了一个按钮来模拟打开深度链接。

请注意,flutter_deep_linking插件的具体API和使用方式可能会随着版本的更新而有所变化,因此请参考最新的官方文档以获取最准确的信息。如果你发现flutter_deep_linking插件不能满足你的需求,你还可以考虑使用其他更广泛使用的深度链接解决方案,如uni_links等。

回到顶部