จะสร้างไฮเปอร์ลิงก์ในวิดเจ็ต Flutter ได้อย่างไร?


97

ฉันต้องการสร้างไฮเปอร์ลิงก์เพื่อแสดงในแอพ Flutter ของฉัน

ควรฝังไฮเปอร์ลิงก์ไว้ในTextมุมมองข้อความที่คล้ายกันเช่น:

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

มีคำแนะนำในการทำสิ่งนี้หรือไม่?

คำตอบ:


161

เพียงพัน InkWell รอบวิดเจ็ตข้อความและจัดหา 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 ไม่มีส่วนหนึ่งของกระพือก็ถูกย้ายไปเป็นปลั๊กอินและ API การเปลี่ยนแปลง
Josef Adamcik

7
นอกจากนี้เราต้องเพิ่มการนำเข้า: import 'package: flutter / gest.dart'; นำเข้า 'แพ็คเกจ: url_launcher / url_launcher.dart';
Alex Pliutau

4
คุณไม่ได้จัดการวงจรชีวิตของคุณTapGestureRecognizerอย่างถูกต้อง คุณต้องเรียกdispose()วิธีการเมื่อRichTextไม่มีการใช้งานอีกต่อไป ดูที่นี่: api.flutter.dev/flutter/painting/TextSpan/recognizer.html
Alex Semeniuk

@AlexSemeniuk ในตัวอย่างของคุณพวกเขากำลังใช้ StatefulWidget ในคำตอบข้างต้นมันคือ StatelessWidget คุณแน่ใจหรือไม่ว่าเราจำเป็นต้องยกเลิกกรณีของ StatelessWidget?
Corey Cole

2
@CoreyCole StatelessWidgetจะไม่ทิ้งของคุณTapGestureRecognizerเพื่อคุณอย่างน่าอัศจรรย์ ในความเป็นจริงการใช้StatelessWidgetในสถานการณ์นี้ไม่ถูกต้องเนื่องจากคุณไม่สามารถกำจัด rsources ด้วยวิธีนี้ได้ และใช่คุณต้องเรียกmethod of อย่างแน่นอนเนื่องจากจะเรียกใช้ตัวจับเวลาภายในซึ่งจำเป็นต้องหยุด dispose()TapGestureRecognizer
Alex Semeniuk

44

Flutter ไม่มีการรองรับไฮเปอร์ลิงก์ในตัว แต่คุณสามารถปลอมได้ด้วยตัวเอง มีตัวอย่างในเรื่องdrawer.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

ฉันไม่แน่ใจว่าคุณหมายถึงอะไรเมื่อ "มองไปไกลกว่าการนำทางในแอป" คุณต้องการให้ลิงก์เปิดเบราว์เซอร์หรือไม่
Collin Jackson

ใช่ลิงก์หรือเหมือนกันที่สามารถคลิกเพื่อเปิดในการเรียกดู
TaylorR

1
นั่นคือสิ่งที่ตัวอย่างที่ฉันเชื่อมโยงไปทำ ฉันเพิ่มรูปภาพบางส่วนในคำตอบเพื่อแสดง
Collin Jackson

ลิงก์ repo เสีย
Michel Feinstein

39

คุณสามารถห่อของคุณTextในและจับคลิกGestureDetectoronTap()

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

7

หากคุณต้องการทำให้ดูเหมือนลิงก์มากยิ่งขึ้นคุณสามารถเพิ่มขีดเส้นใต้:

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

และผลลัพธ์:

ป้อนคำอธิบายภาพที่นี่


ไม่สามารถคลิกได้!
atilkan

จากนั้นพันรอบด้วยวิดเจ็ตปุ่ม :)
bartektartanus

7

คุณสามารถใช้ package 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';
    }
  }
}

1

วิธีอื่น (หรือไม่) ในการใส่ลิงก์ที่คลิกได้ในแอปของคุณ (สำหรับฉันแล้วมันก็ใช้ได้ผลเช่นนั้น):

1 - เพิ่มแพ็คเกจ url_launcher ในไฟล์ pubspec.yaml ของคุณ

(แพ็คเกจเวอร์ชัน 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

0

คุณสามารถใช้ Link Text 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. Philippov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.