Flutter文本链接识别插件native_linkify的使用

发布于 1周前 作者 yibo5220 来自 Flutter

Flutter文本链接识别插件 native_linkify 的使用

native_linkify 是一个用于Flutter的插件,专门用于在纯文本中识别链接。它利用了iOS和macOS上的NSDataDetector以及Android上的Linkify来实现链接识别功能。这使得该插件能够以与大多数原生应用程序相同的方式找到链接,从而提供比现有的纯Dart包更准确的结果。

尽管此插件本身不提供任何可以直接显示内联链接的小部件,但它提供了所有必要的工具,让你可以根据自己的喜好创建这些小部件。

示例Demo

以下是一个完整的示例,展示了如何将文本中的URL、电子邮件和电话号码转换为可点击的链接:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:native_linkify/native_linkify.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final entries = await NativeLinkify.linkify(
      'text link.com some@mail.com and +79990000000');
  runApp(MyApp(entries: entries));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key, required this.entries}) : super(key: key);

  final List<LinkifyEntry> entries;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Text.rich(
            TextSpan(
              children: [
                for (final l in entries)
                  if (l is LinkifyText)
                    // Regular text, text without links
                    TextSpan(
                      text: l.text,
                    )
                  else if (l is LinkifyUrl)
                    // Link
                    TextSpan(
                      text: l.text,
                      style: const TextStyle(color: Colors.blue),
                      recognizer: TapGestureRecognizer()
                        ..onTap = () => launch(l.url),
                    )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

完整的交互式示例

如果你希望有一个更加互动的应用程序,可以考虑下面这个例子。这个例子包括了一个文本输入框,用户可以在其中输入文本,并实时看到被识别为链接的部分变为可点击状态。

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:url_launcher/url_launcher.dart';
import 'package:native_linkify/native_linkify.dart';

const String defaultText = '''
regular text => regular text
link without https:// => google.com
link with https:// => https://google.com
link with subdomain => mail.google.com
e-mail => mail@gmail.com
phone number => +79990000000
cyrillic link => москва.рф
localhost link => https://localhost/
link with non-existing top-level domain => link.cet
link with rare top-level domain => map.yandex
(at the time of writing the example it's recognized well in Android, but not recognized in iOS)
''';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<LinkifyEntry> _links = [];

  [@override](/user/override)
  void initState() {
    super.initState();
    linkify(defaultText);
  }

  Future<void> linkify(String text) async {
    final links = await NativeLinkify.linkify(text);
    if (!mounted) return;
    setState(() {
      _links = links;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Native Linkify',
      home: Scaffold(
        body: SafeArea(
          child: ListView(
            children: [
              TextFormField(
                initialValue: defaultText,
                maxLines: null,
                onChanged: linkify,
                style: const TextStyle(fontSize: 14),
                decoration: const InputDecoration(
                  contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
                ),
              ),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
                child: Text.rich(
                  TextSpan(
                    children: [
                      for (final l in _links)
                        if (l is LinkifyText)
                          TextSpan(text: l.text)
                        else if (l is LinkifyUrl)
                          TextSpan(
                            text: l.text,
                            recognizer: TapGestureRecognizer()..onTap = () => launch(l.url),
                            style: const TextStyle(color: Colors.blue),
                          )
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

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

1 回复

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


当然,以下是如何在Flutter项目中使用native_linkify插件来识别和处理文本链接的一个示例。这个插件可以帮助你自动识别文本中的URL、电子邮件地址、电话号码等,并将它们转换为可点击的链接。

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

dependencies:
  flutter:
    sdk: flutter
  native_linkify: ^0.5.0  # 请检查最新版本号

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

接下来,在你的Dart代码中,你可以使用NativeLinkify小部件来识别和处理文本中的链接。以下是一个简单的示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String textWithLinks = """
  Check out our website at https://www.example.com or send an email to contact@example.com.
  You can also call us at +1-555-555-5555.
  """;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Native Linkify Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: NativeLinkify(
          text: textWithLinks,
          linkStyle: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
          onOpen: (link) async {
            if (await canLaunchUrl(Uri.parse(link))) {
              await launchUrl(Uri.parse(link));
            } else {
              throw 'Could not launch $link';
            }
          },
        ),
      ),
    );
  }
}

在这个示例中:

  1. textWithLinks包含了一些文本,其中包括一个URL、一个电子邮件地址和一个电话号码。
  2. NativeLinkify小部件用于识别和处理这些链接。
  3. linkStyle定义了链接的样式,这里设置为蓝色并带有下划线。
  4. onOpen回调函数用于处理点击链接时的操作。这里使用launchUrl函数来打开URL(需要导入package:url_launcher/url_launcher.dart并使用canLaunchUrllaunchUrl函数)。

注意:为了使用url_launcher,你还需要在pubspec.yaml中添加依赖,并在android/app/src/main/AndroidManifest.xmlios/Runner/Info.plist中添加必要的权限和配置。

dependencies:
  url_launcher: ^6.0.10  # 请检查最新版本号

url_launcher的导入和使用示例:

import 'package:url_launcher/url_launcher.dart';

确保在调用launchUrl之前检查链接是否可以打开,以避免在不支持的平台上抛出异常。

这个示例展示了如何在Flutter应用中使用native_linkify插件来自动识别和处理文本中的链接。希望这对你有所帮助!

回到顶部