Wie erstelle ich einen Hyperlink im Flutter-Widget?

102

Ich möchte einen Hyperlink erstellen, der in meiner Flutter-App angezeigt wird.

Der Hyperlink sollte in eine Textoder ähnliche Textansichten eingebettet sein wie:

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

Irgendwelche Hinweise dazu?

TaylorR
quelle

Antworten:

165

Wickeln Sie einfach ein InkWell um ein Text-Widget und geben Sie einen UrlLauncher (aus der Servicebibliothek) in das onTap-Attribut ein. Installieren Sie UrlLauncher als Flutter-Paket, bevor Sie es unten verwenden.

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')
          ),
        ),
      ),
    );
  }
}

Sie können dem Text-Widget einen Stil zuweisen, damit es wie ein Link aussieht.

Aktualisieren

Nachdem ich mich ein wenig mit dem Problem befasst hatte, fand ich eine andere Lösung, um die von Ihnen gewünschten Inline-Hyperlinks zu implementieren. Sie können das RichText-Widget mit beiliegenden TextSpans verwenden .

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');
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Auf diese Weise können Sie tatsächlich ein Wort hervorheben und daraus einen Hyperlink erstellen;)

Rainer Wittmann
quelle
7
UrlLauncher ist nicht mehr Teil des Flatterns, es wurde in ein Plugin verschoben und die API geändert .
Josef Adamcik
7
Außerdem müssen wir Importe hinzufügen: import 'package: flutter / gestures.dart'; import 'package: url_launcher / url_launcher.dart';
Alex Pliutau
5
Sie behandeln den Lebenszyklus Ihres Unternehmens nicht TapGestureRecognizerrichtig. Sie müssen die dispose()Methode aufrufen , wenn sie RichTextnicht mehr verwendet wird. Siehe hier: api.flutter.dev/flutter/painting/TextSpan/recognizer.html
Alex Semeniuk
@AlexSemeniuk In Ihrem Beispiel verwenden sie ein StatefulWidget, in der obigen Antwort ist es ein StatelessWidget. Sind Sie sicher, dass wir den Fall eines StatelessWidget beseitigen müssen?
Corey Cole
2
@CoreyCole StatelessWidgetwird Ihre nicht auf magische Weise TapGestureRecognizerfür Sie entsorgen . Tatsächlich ist die Verwendung StatelessWidgetin diesem Szenario falsch, da Sie Ihre Ressourcen nicht auf diese Weise entsorgen können. Und ja, Sie müssen unbedingt die dispose()Methode von aufrufen TapGestureRecognizer, da sie den internen Timer ausführt, der gestoppt werden muss.
Alex Semeniuk
48

Flutter hat keine integrierte Hyperlink-Unterstützung, aber Sie können es selbst fälschen. Es gibt ein Beispiel in der Schublade der Galerie . Sie verwenden ein RichTextWidget mit einer Farbe TextSpan, die ein recognizerAttribut für den Umgang mit Taps hat:

        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,
              ),
            ],
          ),

Hyperlink Browser

Collin Jackson
quelle
Vielen Dank. Aber das ist nicht wirklich das, wonach ich suche: Ich schaue über die In-App-Navigation hinaus.
TaylorR
Ich bin mir nicht sicher, was Sie unter "Blick über die In-App-Navigation hinaus" verstehen. Möchten Sie, dass der Link einen Browser öffnet?
Collin Jackson
Ja, ein Link oder ähnliches, auf den geklickt werden kann, um ihn beim Durchsuchen zu öffnen.
TaylorR
1
Das ist es, was das Beispiel, mit dem ich verlinkt habe, tut. Ich habe der Antwort einige Bilder hinzugefügt, um sie zu zeigen.
Collin Jackson
Die Repo-Verbindung ist unterbrochen
Michel Feinstein
40

Sie können Ihr TextIn einpacken GestureDetectorund das Click-In bearbeiten 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
  }
)

Geben Sie hier die Bildbeschreibung ein

CopsOnRoad
quelle
Sie haben Recht, Ihre Lösung hat weniger Zeilen als die anderer, aber Inkwell ist das Widget für diesen speziellen Job, also denke ich zumindest semantisch, dass es die beste Lösung ist
dmarquina
2
@dmarquina Ja, Sie können InkWellanstelle von verwenden GestureDetector.
CopsOnRoad
8

Sie können das Paket flutter_linkify
https://pub.dev/packages/flutter_linkify verwenden. Sie
möchten lediglich eine weitere Option bereitstellen.
Das Paket teilt Ihren Text und hebt http / https automatisch hervor.
Kombinieren Sie das Plugin url_launcher. Sie können die URL starten.
Sie können das folgende Beispiel überprüfen:

Geben Sie hier die Bildbeschreibung ein

vollständiger Code unten

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: [email protected] \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';
    }
  }
}
Chunhunghan
quelle
Wie können Sie 2 Links auf demselben Widget haben? Zum Beispiel "Wenn Sie darauf klicken, akzeptieren Sie die Nutzungsbedingungen und Datenschutzbestimmungen", wo wir sie zusammen haben müssen
Dani
7

Wenn Sie möchten, dass es noch mehr wie ein Link aussieht, können Sie Folgendes unterstreichen:

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

und das Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Bartektartanus
quelle
Es ist nicht anklickbar!
Atilkan
Wickeln Sie es dann mit dem Button-Widget ein. :)
bartektartanus
1

Eine alternative (oder nicht) Möglichkeit, anklickbare Links in Ihre App einzufügen (für mich hat es einfach so funktioniert):

1 - Fügen Sie das Paket url_launcher in Ihre Datei pubspec.yaml ein

(Die Paketversion 5.0 hat bei mir nicht gut funktioniert, daher verwende ich 4.2.0 + 3).

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

2 - Importieren Sie es und verwenden Sie es wie folgt.

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';
    }
  }
}
Fellipe Sanches
quelle
Wenn Sie einen Hyperlink zwischen einem Text benötigen, können Sie einen FlatButtonmit demselben Hintergrund und denselben Textfarben wie der Rest Ihrer Texte verwenden. Formatieren Sie ihn also mit TextDecoration.underline, wie der oben gezeigte Bartektartanus zeigt ...
Fellipe Sanches
1

Sie können Link Text https://pub.dev/packages/link_text verwenden und wie folgt verwenden

 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,
      ),
    ),
  );
}
Syed Ahsan Ali
quelle
Unter Linux flutter pub getscheitert es mitUnable to find a plugin.vcxproj for plugin "url_launcher_windows"
Eugene Gr. Philippov