首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Flutter中链接文本

如何在Flutter中链接文本
EN

Stack Overflow用户
提问于 2018-08-23 19:46:48
回答 4查看 10.7K关注 0票数 16

在Flutter中,有没有一种简单的方法来“链接”可能包含纯文本、电子邮件和web URL的文本?例如,如果我的文本是My phone number is 099 123 45 67 and my email is test@test.com,则电话号码和电子邮件将被呈现为可点击的链接。

在Android中,它会是一行代码:

代码语言:javascript
运行
复制
textView.setAutoLinkMask(Linkify.ALL);

我已经看到一个类似的问题被问到了here。这种解决方案对静态文本很有效,但对于动态文本,解析文本、检测所有URL、电话号码、电子邮件等并使用TextSpan进行相应的渲染会复杂得多。

EN

回答 4

Stack Overflow用户

发布于 2018-09-19 07:04:45

我为此创建了一个新的包:flutter_linkify。目前仅支持URLS,但您可以随时在有功能请求的GitHub上提交问题。

Baisc用法:

代码语言:javascript
运行
复制
import 'package:flutter_linkify/flutter_linkify.dart';

Linkify(
  onOpen: (url) => print("Clicked $url!"),
  text: "Made by https://cretezy.com",
);
票数 18
EN

Stack Overflow用户

发布于 2019-10-13 16:21:40

下面是我如何实现它的--使用buildTextWithLinks函数来获得一个带有链接的Text组件。

它使用url_launcher,目前支持网址,邮件和电话链接,但可以很容易地通过添加更多的RegExp和处理器进行扩展。

代码语言:javascript
运行
复制
import 'package:url_launcher/url_launcher.dart';

Text buildTextWithLinks(String textToLink) => Text.rich(TextSpan(children: linkify(textToLink)));

Future<void> openUrl(String url) async {
  if (await canLaunch(url)) {
    await launch(url);
  } else {
    throw 'Could not launch $url';
  }
}

const String urlPattern = r'https?:/\/\\S+';
const String emailPattern = r'\S+@\S+';
const String phonePattern = r'[\d-]{9,}';
final RegExp linkRegExp = RegExp('($urlPattern)|($emailPattern)|($phonePattern)', caseSensitive: false);

WidgetSpan buildLinkComponent(String text, String linkToOpen) => WidgetSpan(
    child: InkWell(
      child: Text(
        text,
        style: TextStyle(
          color: Colors.blueAccent,
          decoration: TextDecoration.underline,
        ),
      ),
      onTap: () => openUrl(linkToOpen),
    )
);

List<InlineSpan> linkify(String text) {
  final List<InlineSpan> list = <InlineSpan>[];
  final RegExpMatch match = linkRegExp.firstMatch(text);
  if (match == null) {
    list.add(TextSpan(text: text));
    return list;
  }

  if (match.start > 0) {
    list.add(TextSpan(text: text.substring(0, match.start)));
  }

  final String linkText = match.group(0);
  if (linkText.contains(RegExp(urlPattern, caseSensitive: false))) {
    list.add(buildLinkComponent(linkText, linkText));
  }
  else if (linkText.contains(RegExp(emailPattern, caseSensitive: false))) {
    list.add(buildLinkComponent(linkText, 'mailto:$linkText'));
  }
  else if (linkText.contains(RegExp(phonePattern, caseSensitive: false))) {
    list.add(buildLinkComponent(linkText, 'tel:$linkText'));
  } else {
    throw 'Unexpected match: $linkText';
  }

  list.addAll(linkify(text.substring(match.start + linkText.length)));

  return list;
}
票数 6
EN

Stack Overflow用户

发布于 2018-12-04 21:21:25

感谢@Charles Crete创建了这个库。

我只想在这里通过组合RichText、TextSpan和TapGestureRecognizer (都在Flutter框架中)再添加一个解决方案。

代码语言:javascript
运行
复制
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

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

class HyperLinkDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: RichText(
                text: TextSpan(children: [
              TextSpan(
                  text: 'This is a very long text, but you can not click on it. ',
                  style: TextStyle(fontSize: 20, color: Colors.black)),
              TextSpan(
                  text: 'And this is a clickable text',
                  style: TextStyle(
                      fontSize: 20,
                      color: Colors.blue,
                      decoration: TextDecoration.underline),
                  recognizer: TapGestureRecognizer()
                    ..onTap = () {
                      print('You clicked on me!');
                    })
            ])),
          ),
        ),
      ),
    );
  }
}

结果如下所示

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51985111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档