Flutter widget'ında bir köprü nasıl oluşturulur?


97

Flutter uygulamamda görüntülenecek bir köprü oluşturmak istiyorum.

Köprü bağlantısı aşağıdakiler Textgibi bir veya benzer metin görünümlerine gömülmelidir:

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

Bunu yapmak için herhangi bir ipucu var mı?

Yanıtlar:


162

Bir InkWell'i bir Metin parçacığının etrafına sarın ve onTap özniteliğine bir UrlLauncher (hizmet kitaplığından) sağlayın. UrlLauncher'ı aşağıda kullanmadan önce bir Flutter paketi olarak kurun .

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

Metin widget'ına bağlantı gibi görünmesi için bir stil sağlayabilirsiniz.

Güncelleme

Konuya biraz baktıktan sonra, istediğiniz 'satır içi' köprüleri uygulamak için farklı bir çözüm buldum. Sen kullanabilirsiniz RichText Widget kapalı olan 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');
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

Bu şekilde aslında bir kelimeyi vurgulayabilir ve ondan bir köprü oluşturabilirsiniz;)


7
UrlLauncher artık flutter'ın bir parçası değil, bir eklentiye taşındı ve API değiştirildi .
Josef Adamcik

7
Ayrıca içe aktarmalar eklememiz gerekiyor: import 'package: flutter / gestures.dart'; ithal 'paket: url_launcher / url_launcher.dart';
Alex Pliutau

5
Yaşam döngüsünü TapGestureRecognizerdoğru şekilde idare etmiyorsunuz . Artık kullanılmadığında dispose()yöntemi çağırmanız gerekir RichText. Buraya bakın: api.flutter.dev/flutter/painting/TextSpan/recognizer.html
Alex Semeniuk

@AlexSemeniuk Örneğinizde bir StatefulWidget kullanıyorlar, yukarıdaki cevapta bir StatelessWidget. StatelessWidget davasını elden çıkarmamız gerektiğinden emin misiniz?
Corey Cole

2
@CoreyCole StatelessWidgetsizin TapGestureRecognizeriçin sihirli bir şekilde elden çıkarmaz . Aslında, StatelessWidgetbu senaryoda kullanmak yanlıştır, çünkü kaynaklarınızı bu şekilde elden çıkaramazsınız. Ve evet, kesinlikledispose() yöntemini çağırmanız gerekiyor TapGestureRecognizerçünkü durdurulması gereken dahili zamanlayıcıyı çalıştırıyor.
Alex Semeniuk

44

Flutter'ın yerleşik köprü desteği yoktur, ancak bunu kendiniz taklit edebilirsiniz. Galerinin drawer.dart dosyasında bir örnek var . Dokunmaları işlemek için bir niteliğe sahip RichTextrenkli içeren bir widget kullanırlar :TextSpanrecognizer

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

köprü tarayıcı


Teşekkürler. Ancak aradığım şey bu değil: Uygulama içi navigasyonun ötesine bakıyorum.
TaylorR

"Uygulama içi gezinmenin ötesine bakmak" ile ne demek istediğinizden emin değilim. Bağlantının bir tarayıcı açmasını istiyor musunuz?
Collin Jackson

Evet, bir göz atmada açmak için tıklanabilen bir bağlantı veya benzeri.
TaylorR

1
Bağlandığım örnek bunu yapıyor. Göstermek için cevaba bazı resimler ekledim.
Collin Jackson

Depo bağlantısı koptu
Michel Feinstein

39

Eğer sarabilirsiniz Textin GestureDetectorve sap tıklayın 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
  }
)

görüntü açıklamasını buraya girin


Haklısınız, çözümünüzün diğerlerinden daha az satırı var, ancak Inkwell bu özel iş için bir araç, bu yüzden en azından anlamsal olarak bunun en iyi çözüm olduğunu düşünüyorum
dmarquina

2
@dmarquina Evet, InkWellyerine kullanabilirsiniz GestureDetector.
CopsOnRoad

7

Daha çok bir bağlantı gibi görünmesini istiyorsanız, alt çizgi ekleyebilirsiniz:

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

ve sonuç:

görüntü açıklamasını buraya girin


Tıklanabilir değil!
atilkan

Ardından Button widget'ıyla etrafına sarın. :)
bartektartanus

7

Flutter_linkify paketini kullanabilirsiniz
https://pub.dev/packages/flutter_linkify
Sadece başka bir seçenek sağlamak istiyorum.
Paket metninizi böler ve vurgular http / https'yi otomatik olarak
birleştirin Eklentiyi birleştir url_launcher url'yi başlatabilirsiniz
Aşağıdaki örneği kontrol edebilirsiniz:

görüntü açıklamasını buraya girin

aşağıdaki kodun tamamı

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

Aynı widget üzerinde nasıl 2 bağlantıya sahip olabilirsiniz? Örneğin, bunları bir araya
getirmemiz

1

Uygulamanıza tıklanabilir bağlantılar koymanın alternatif (veya değil) bir yolu (benim için sadece bu şekilde çalıştı):

1 - url_launcher paketini pubspec.yaml dosyanıza ekleyin

(paket sürüm 5.0 benim için iyi çalışmadı, bu yüzden 4.2.0 + 3 kullanıyorum).

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

2 - İçe aktarın ve aşağıdaki gibi kullanın.

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

Bir metin arasında bir hiperlinke ihtiyaç duyarsanız, metinlerinizle FlatButtonaynı arka plan ve metin renklerine sahip bir metin kullanabilirsiniz , bu nedenle bartektartanus'un yukarıda gösterdiği gibi TextDecoration.underline ile biçimlendirin ...
Fellipe Sanches

0

Bağlantı Metni https://pub.dev/packages/link_text'i kullanabilir ve şu şekilde kullanabilirsiniz:

 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 altında flutter pub getbunun için başarısız oluyorUnable to find a plugin.vcxproj for plugin "url_launcher_windows"
Eugene Gr. Philippov
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.