Bagaimana cara membuat hyperlink di widget Flutter?

97

Saya ingin membuat hyperlink untuk ditampilkan di aplikasi Flutter saya.

Tautan hiper harus disematkan dalam Texttampilan teks atau serupa seperti:

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

Ada petunjuk untuk melakukan ini?

TaylorR
sumber

Jawaban:

161

Cukup gabungkan InkWell di sekitar widget Teks dan berikan UrlLauncher (dari pustaka layanan) ke atribut onTap. Instal UrlLauncher sebagai paket Flutter sebelum menggunakannya di bawah.

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

Anda dapat memberikan gaya ke widget Teks agar terlihat seperti tautan.

Memperbarui

Setelah melihat masalah sedikit, saya menemukan solusi berbeda untuk menerapkan hyperlink 'sejalan' yang Anda minta. Anda dapat menggunakan Widget RichText dengan TextSpans tertutup .

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

Dengan cara ini Anda benar-benar dapat menyorot satu kata dan membuat hyperlink darinya;)

Rainer Wittmann
sumber
7
UrlLauncher bukan lagi bagian dari flutter, itu telah dipindahkan ke plugin dan API berubah .
Josef Adamcik
7
Juga kita perlu menambahkan impor: import 'package: flutter / gestures.dart'; impor 'paket: url_launcher / url_launcher.dart';
Alex Pliutau
5
Anda tidak menangani siklus hidup Anda TapGestureRecognizerdengan benar. Anda harus memanggil dispose()metode saat RichTexttidak lagi digunakan. Lihat di sini: api.flutter.dev/flutter/painting/TextSpan/recognizer.html
Alex Semeniuk
@AlexSemeniuk Dalam contoh Anda, mereka menggunakan StatefulWidget, pada jawaban di atas adalah StatelessWidget. Apakah Anda yakin kami perlu membuang kasus StatelessWidget?
Corey Cole
2
@CoreyCole StatelessWidgettidak akan secara ajaib membuang milik Anda TapGestureRecognizeruntuk Anda. Faktanya, menggunakan StatelessWidgetskenario ini tidak benar, karena Anda tidak dapat membuang sumber daya Anda dengan cara ini. Dan ya, Anda tentu saja - perlu memanggil dispose()metode TapGestureRecognizer, karena ini menjalankan pengatur waktu internal yang perlu dihentikan.
Alex Semeniuk
44

Flutter tidak memiliki dukungan hyperlink bawaan, tetapi Anda dapat memalsukannya sendiri. Ada contohnya di drawer.dart Galeri . Mereka menggunakanRichText widget yang berisi berwarna TextSpan, yang memiliki recognizeratribut untuk menangani ketukan:

        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
sumber
Terima kasih. Tapi sebenarnya bukan ini yang saya cari: Saya melihat lebih dari sekadar navigasi dalam aplikasi.
TaylorR
Saya tidak yakin apa yang Anda maksud dengan "melihat di luar navigasi dalam aplikasi". Apakah Anda ingin tautan untuk membuka browser?
Collin Jackson
Ya, link atau sejenisnya yang bisa diklik untuk membuka di browsing.
TaylorR
1
Itulah yang dilakukan sampel yang saya tautkan. Saya menambahkan beberapa gambar ke jawaban untuk menunjukkannya.
Collin Jackson
Tautan repo rusak
Michel Feinstein
39

Anda dapat membungkus Anda Textdalam GestureDetectordan menangani klik di 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
  }
)

masukkan deskripsi gambar di sini

CopsOnRoad
sumber
Anda benar, solusi Anda memiliki lebih sedikit garis daripada yang lain, tetapi Inkwell adalah widget untuk pekerjaan khusus ini, jadi setidaknya secara semantik menurut saya Ini adalah solusi terbaik
dmarquina
2
@dmarquina Ya, Anda dapat menggunakan InkWellbukan GestureDetector.
CopsOnRoad
7

Jika Anda ingin membuatnya lebih terlihat seperti link, Anda dapat menambahkan garis bawah:

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

dan hasilnya:

masukkan deskripsi gambar di sini

bartektartanus
sumber
Itu tidak bisa diklik!
atilkan
Kemudian bungkus dengan widget Tombol. :)
bartektartanus
7

Anda dapat menggunakan paket flutter_linkify
https://pub.dev/packages/flutter_linkify
Hanya ingin memberikan opsi lain.
Paket akan membagi teks Anda dan menyorot http / https secara otomatis
Gabungkan plugin url_launcher Anda dapat meluncurkan url
Anda dapat memeriksa contoh di bawah ini:

masukkan deskripsi gambar di sini

kode lengkap di bawah ini

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
sumber
Bagaimana Anda bisa memiliki 2 tautan pada widget yang sama? Seperti misalnya "dengan mengklik ini Anda menerima persyaratan penggunaan dan kebijakan privasi" di mana kita perlu memilikinya bersama
Dani
1

Cara alternatif (atau tidak) untuk menempatkan tautan yang dapat diklik di aplikasi Anda (bagi saya itu hanya bekerja seperti itu):

1 - Tambahkan paket url_launcher di file pubspec.yaml Anda

(paket versi 5.0 tidak bekerja dengan baik untuk saya, jadi saya menggunakan 4.2.0 + 3).

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

2 - Impor dan gunakan seperti di bawah ini.

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
sumber
Jika memerlukan hyperlink antara beberapa teks, Anda dapat menggunakan FlatButtondengan latar belakang dan warna teks yang sama dengan teks Anda lainnya, jadi formatlah dengan TextDecoration.underline seperti yang ditunjukkan bartektartanus di atas ...
Fellipe Sanches
0

Anda dapat menggunakan Teks Tautan https://pub.dev/packages/link_text dan menggunakannya seperti

 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
sumber
Di Linux flutter pub getuntuk itu gagal denganUnable to find a plugin.vcxproj for plugin "url_launcher_windows"
Eugene Gr. Philippov