Flutter外部链接处理插件external_links的使用
Flutter外部链接处理插件external_links的使用
一个用于处理应用外部链接的包,提供了一个统一的接口来处理推送通知、深度链接、动态链接等。
组件
ExternalLink
ExternalLink
对象表示链接信息。它包含以下属性和方法:
title
: 链接的标题,通常与推送通知的标题相关联。content
: 链接的内容,通常与推送通知的内容相关联。args
: 链接的参数,通常与推送通知的参数相关联。uri
: 链接的 URI,通常与深度链接的 URI 相关联。authenticationRequired
: 是否需要登录才能处理此链接。getHandler
: 返回链接的处理器。如果不需要操作处理器,则返回一个EmptyHandler
实例。mapFactory
: 用于从Map<String, dynamic>
创建链接。尽快分配。uriFactory
: 用于从Uri
创建链接。尽快分配。
示例代码:
class DummyLink extends ExternalLink {
[@override](/user/override)
Map<String, dynamic> get args => {};
[@override](/user/override)
bool get authenticationRequired => false;
[@override](/user/override)
String get content => 'Dummy content! #${Random().nextInt(100000)}';
[@override](/user/override)
ExternalLinkHandler getHandler([BuildContext context]) {
if (context != null) {
return DummyLinkHandler(context);
} else {
return EmptyHandler();
}
}
[@override](/user/override)
String get title => 'Dummy title!';
[@override](/user/override)
Uri get uri => null;
}
ExternalLinkHandler 和 ExternalLinkContextHandler
链接的处理器。用于在处理链接时执行操作。
ExternalLinkHandler
: 如果你的操作不需要BuildContext
,可以使用这个类。ExternalLinkContextHandler
: 如果你的操作需要BuildContext
,可以使用这个类。
示例代码:
class DummyLinkHandler extends ExternalLinkContextHandler {
DummyLinkHandler(BuildContext context) : super(context);
[@override](/user/override)
Future<void> processLinkWithContext(BuildContext context, ExternalLink link) {
return showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text(link.title ?? ''),
content: Text(link.content ?? ''),
),
);
}
}
ExternalLinksAdapter
适配器,用于将信息处理成 ExternalLink
,并自动将其加入到 ExternalLinksBloc
的队列中。
示例代码:
class DummyAdapter extends ExternalLinksAdapter {
[@override](/user/override)
Future<void> init() async {}
void triggerDummy(Uri uri) => emit(
ExternalLink.uriFactory(uri),
);
}
ExternalLinksBloc
管理链接队列的 Bloc。
示例代码:
BlocProvider<ExternalLinksBloc>(
create: (_) => ExternalLinksBloc(
adapters: [
DummyAdapter()..init(), // 一个适配器用于处理深度链接
],
),
child: // 子组件,通常是 MaterialApp
)
ExternalLinksListener
这是一个方便类,监听 ExternalLink
队列并使用它们的处理器进行处理。你可以选择直接监听 ExternalLinksBloc
并决定如何处理收到的链接。
示例代码:
class ExternalLinksListener extends StatelessWidget {
final Widget child;
const ExternalLinksListener({
Key? key,
required this.child,
}) : super(key: key);
[@override](/user/override)
Widget build(BuildContext context) {
return BlocListener<ExternalLinksBloc, ExternalLinksState>(
listenWhen: (previous, current) => current is ExternalLinkAvailable,
listener: (context, state) {
if (state is ExternalLinkAvailable) {
BlocProvider.of<ExternalLinksBloc>(context).add(
ProcessLink(
processFunction: (link) {
return link.getHandler(context).processLink(link);
},
),
);
}
},
child: child,
);
}
}
ExternalLink 工厂
ExternalLink
类有两个函数可以用作工厂来创建链接:
mapFactory
: 用于从Map<String, dynamic>
创建链接。uriFactory
: 用于从Uri
创建链接。
默认情况下,这些函数返回 null
。如果你想使用它们,只需为它们分配一个新的 Function
对象。
考虑事项
虽然一开始可能看起来过于复杂,但在我的经验中,一个能够以简单方式处理应用外部链接的坚实架构,在长期运行中可能是救命稻草。
只需设置你想要接收链接信息的适配器数量,并定义你需要的链接类型。尽管名字叫 Link
,你实际上也可以用它作为应用程序内部的通知系统,或者连接到 WebSocket 等。
假设你在管理深度链接,并且目前管理两个 URL。每当需要新的 URL 时,只需定义另一个链接及其处理器,并更新工厂函数以返回该链接。不需要其他任何操作。
我在几个项目(包括企业项目)中使用过这种架构,并证明了其在长期内非常有用。
完整示例
以下是完整的示例代码:
import 'dart:math';
import 'package:external_links/external_links.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() {
ExternalLink.uriFactory = (uri) {
if (uri.path == '/dummy') {
return DummyLink();
} else {
return DummierLink();
}
};
runApp(MyApp());
}
class DummyLink extends ExternalLink {
[@override](/user/override)
Map<String, dynamic> get args => {};
[@override](/user/override)
bool get authenticationRequired => false;
[@override](/user/override)
String get content => 'Dummy content! #${Random().nextInt(100000)}';
[@override](/user/override)
ExternalLinkHandler getHandler([BuildContext context]) {
if (context != null) {
return DummyLinkHandler(context);
} else {
return EmptyHandler();
}
}
[@override](/user/override)
String get title => 'Dummy title!';
[@override](/user/override)
Uri get uri => null;
}
class DummierLink extends ExternalLink {
[@override](/user/override)
Map<String, dynamic> get args => {};
[@override](/user/override)
bool get authenticationRequired => false;
[@override](/user/override)
String get content => 'Dummier content! #${Random().nextInt(100000)}';
[@override](/user/override)
ExternalLinkHandler getHandler([BuildContext context]) {
if (context != null) {
return DummyLinkHandler(context);
} else {
return EmptyHandler();
}
}
[@override](/user/override)
String get title => 'Dummier title!';
[@override](/user/override)
Uri get uri => null;
}
class DummyLinkHandler extends ExternalLinkContextHandler {
DummyLinkHandler(BuildContext context) : super(context);
[@override](/user/override)
Future<void> processLinkWithContext(BuildContext context, ExternalLink link) {
return showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text(link.title ?? ''),
content: Text(link.content ?? ''),
),
);
}
}
class DummyAdapter extends ExternalLinksAdapter {
[@override](/user/override)
Future<void> init() async {}
void triggerDummy(Uri uri) => emit(
ExternalLink.uriFactory(uri),
);
}
final dummyAdapter = DummyAdapter();
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return BlocProvider<ExternalLinksBloc>(
create: (_) => ExternalLinksBloc(
adapters: [
dummyAdapter..init(),
],
),
child: MaterialApp(
title: 'External Links Demo',
home: Home(),
),
);
}
}
class Home extends StatefulWidget {
[@override](/user/override)
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
[@override](/user/override)
Widget build(BuildContext context) {
return ExternalLinksListener(
child: Scaffold(
appBar: AppBar(
title: Text('External links demo'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ElevatedButton(
onPressed: () => dummyAdapter.triggerDummy(Uri.parse('http://dummy.dummy/dummy')),
child: Text('Trigger dummy'),
),
ElevatedButton(
onPressed: () => dummyAdapter.triggerDummy(Uri.parse('http://dummy.dummy/dummier')),
child: Text('Trigger dummier'),
),
],
),
),
);
}
}
更多关于Flutter外部链接处理插件external_links的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter外部链接处理插件external_links的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,我可以为你提供一个关于如何在Flutter应用中使用external_links
插件来处理外部链接的代码示例。external_links
插件允许你轻松地在Flutter应用中打开外部链接,无论是Web URL、电子邮件地址还是电话号码等。
首先,你需要在你的pubspec.yaml
文件中添加external_links
插件的依赖:
dependencies:
flutter:
sdk: flutter
external_links: ^0.4.0 # 请检查最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter应用中,你可以按照以下方式使用external_links
插件来处理外部链接:
1. 导入插件
在你的Dart文件中,导入external_links
插件:
import 'package:external_links/external_links.dart';
2. 使用插件
你可以使用ExternalLinks
类的方法来打开不同类型的外部链接。以下是一个简单的示例,展示如何在按钮点击时打开一个Web URL、发送电子邮件和拨打电话号码:
import 'package:flutter/material.dart';
import 'package:external_links/external_links.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('External Links Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () async {
await ExternalLinks.openUrl("https://www.example.com");
},
child: Text('Open Web URL'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
await ExternalLinks.sendEmail(["test@example.com"], "Subject", "Body");
},
child: Text('Send Email'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
await ExternalLinks.dialPhoneNumber("+1234567890");
},
child: Text('Dial Phone Number'),
),
],
),
),
),
);
}
}
3. 权限处理
对于拨打电话和发送电子邮件的功能,你可能需要在AndroidManifest.xml
中声明相应的权限。例如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
...>
...
</application>
</manifest>
注意:在实际应用中,处理拨打电话和发送短信等敏感操作时,应确保遵循相关隐私政策和用户授权机制。
这个示例展示了如何使用external_links
插件在Flutter应用中处理不同类型的外部链接。你可以根据需要扩展和修改这个示例。