如何在Flutter小部件中创建超链接?


103

我想创建一个超链接以显示在我的Flutter应用中。

超级链接应嵌入一个Text或类似的文本视图中,例如:

The last book bought is <a href='#'>this</a>

有任何提示吗?

Answers:


169

只需将InkWell包裹在Text小部件周围,并将UrlLauncher(来自服务库)提供给onTap属性。将UrlLauncher作为Flutter软件包安装,然后在下面使用。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';


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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('UrlLauchner'),
        ),
        body: new Center(
          child: new InkWell(
              child: new Text('Open Browser'),
              onTap: () => launch('https://docs.flutter.io/flutter/services/UrlLauncher-class.html')
          ),
        ),
      ),
    );
  }
}

您可以向“文本”小部件提供样式,以使其看起来像一个链接。

更新资料

在仔细研究了这个问题之后,我发现了一个不同的解决方案来实现您要求的“行内”超链接。您可以将RichText Widget与附带的TextSpans一起使用

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('UrlLauchner'),
        ),
        body: new Center(
          child: new RichText(
            text: new TextSpan(
              children: [
                new TextSpan(
                  text: 'This is no Link, ',
                  style: new TextStyle(color: Colors.black),
                ),
                new TextSpan(
                  text: 'but this is',
                  style: new TextStyle(color: Colors.blue),
                  recognizer: new TapGestureRecognizer()
                    ..onTap = () { launch('https://docs.flutter.io/flutter/services/UrlLauncher-class.html');
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

这样,您实际上就可以突出显示一个单词,并在其中创建超链接;)


7
UrlLauncher不再是flutter的一部分,它已移至插件且API更改了
约瑟夫·亚当奇克

7
我们还需要添加导入:import'package:package:flutter / gestures.dart'; 导入'package:url_launcher / url_launcher.dart';
亚历克斯·普留陶

5
您没有TapGestureRecognizer正确处理生命周期。您必须在不再使用dispose()时调用方法RichText。参见此处:api.flutter.dev/flutter/painting/TextSpan/recognizer.html
Alex Semeniuk

@AlexSemeniuk在您的示例中,他们使用的是StatefulWidget,在上面的答案中是StatelessWidget。您确定我们需要处理StatelessWidget的情况吗?
科里·科尔

2
@CoreyColeStatelessWidget不会神奇地TapGestureRecognizer为您处置您。实际上,StatelessWidget在这种情况下使用是不正确的,因为您不能以这种方式处置您的资源。是的,您绝对需要调用dispose()方法TapGestureRecognizer,因为它运行需要停止的内部计时器。
Alex Semeniuk

50

Flutter没有内置的超链接支持,但是您可以自己伪造它。图库的gallery.dart中有一个示例。他们使用RichText包含彩色的小部件TextSpan,该小部件具有recognizer处理水龙头的属性:

        RichText(
          text: TextSpan(
            children: [
              TextSpan(
                style: bodyTextStyle,
                text: seeSourceFirst,
              ),
              TextSpan(
                style: bodyTextStyle.copyWith(
                  color: colorScheme.primary,
                ),
                text: repoText,
                recognizer: TapGestureRecognizer()
                  ..onTap = () async {
                    final url = 'https://github.com/flutter/gallery/';
                    if (await canLaunch(url)) {
                      await launch(
                        url,
                        forceSafariVC: false,
                      );
                    }
                  },
              ),
              TextSpan(
                style: bodyTextStyle,
                text: seeSourceSecond,
              ),
            ],
          ),

超连结 浏览器


谢谢。但是,这并不是我真正想要的东西:我不仅在应用程序内导航之外。
TaylorR

我不确定“超越应用内导航”的含义。您要链接打开浏览器吗?
科林·杰克逊

是的,可以单击链接以在浏览器中打开之类的链接。
TaylorR

1
这就是我链接的示例所做的。我在答案中添加了一些图片以显示它。
科林·杰克逊

回购链接已断开
Michel Feinstein,

41

你可以用你TextGestureDetector和手柄的点击中onTap()

GestureDetector(
  child: Text("Click here", style: TextStyle(decoration: TextDecoration.underline, color: Colors.blue)),
  onTap: () {
    // do what you need to do when "Click here" gets clicked
  }
)

在此处输入图片说明


没错,您的解决方案比其他解决方案少一些,但是Inkwell是完成此特定任务的小部件,因此至少从语义上来说,我认为这是最佳的解决方案
dmarquina

2
@dmarquina是的,您可以使用InkWell代替GestureDetector
CopsOnRoad '19

9

如果您想使其看起来更像一个链接,则可以添加下划线:

new Text("Hello Flutter!", style: new TextStyle(color: Colors.blue, decoration: TextDecoration.underline),)

结果:

在此处输入图片说明


它不可点击!
atilkan

然后使用Button小部件将其包装起来。:)
bartektartanus

8

您可以使用包flutter_linkify
https://pub.dev/packages/flutter_linkify
只是想提供另一个选择。
软件包将分割您的文本并自动突出显示http / https
组合插件url_launcher您可以启动url
您可以查看以下示例:

在此处输入图片说明

下面的完整代码

import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'dart:async';

import 'package:url_launcher/url_launcher.dart';

void main() => runApp(new LinkifyExample());

class LinkifyExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'flutter_linkify example',
      home: Scaffold(
        appBar: AppBar(
          title: Text('flutter_linkify example'),
        ),
        body: Center(
          child: Linkify(
            onOpen: _onOpen,
            text: "Made by https://cretezy.com \n\nMail: example@gmail.com \n\n  this is test http://pub.dev/ ",
          ),
        ),
      ),
    );
  }

  Future<void> _onOpen(LinkableElement link) async {
    if (await canLaunch(link.url)) {
      await launch(link.url);
    } else {
      throw 'Could not launch $link';
    }
  }
}

在同一个小部件上如何有2个链接?就像“需要单击以接受使用条款和隐私政策”这样的示例,我们需要将它们放在一起
Dani

1

在您的应用中放置可点击链接的另一种方法(或不是) (对我而言,它就是这样):

1-在pubspec.yaml文件中添加url_launcher包

(5.0版的软件包对我而言效果不佳,因此我使用的是4.2.0 + 3)。

dependencies:
  flutter:
    sdk: flutter
  url_launcher: ^4.2.0+3

2-导入并按以下方式使用。

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

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    home: MyUrl(),
  ));
}

class MyUrl extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Url Launcher'),
      ),
      body: Center(
        child: FlatButton(
          onPressed: _launchURL,
          child: Text('Launch Google!',
              style: TextStyle(fontSize: 17.0)),
        ),
      ),
    );
  }

  _launchURL() async {
    const url = 'https://google.com.br';
    if (await canLaunch(url)) {
      await launch(url);
    } else {
      throw 'Could not launch $url';
    }
  }
}

如果需要某些文本之间的超链接,则可以使用FlatButton与其余文本相同的背景和文本颜色,因此将其格式化为TextDecoration.underline,如上面的bartektartanus所示...
Fellipe Sanches

1

您可以使用链接文本https://pub.dev/packages/link_text 并像

 final String _text = 'Lorem ipsum https://flutter.dev\nhttps://pub.dev'; 
 @override
 Widget build(BuildContext context) {
 return Scaffold(
     body: Center(
      child: LinkText(
        text: _text,
        textAlign: TextAlign.center,
      ),
    ),
  );
}

在Linux下flutter pub get,它因Unable to find a plugin.vcxproj for plugin "url_launcher_windows"
Eugene Gr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.