232 votes

Comment créer un lien hypertexte dans un widget Flutter?

Je voudrais créer un lien hypertexte à afficher dans mon application Flutter.

Le lien hypertexte devrait être intégré dans un Text ou des vues de texte similaires comme :

Le dernier livre acheté est [celui-ci](#)

Une astuce pour le faire ?

0 votes

326voto

Rainer Wittmann Points 2276

Il suffit d'envelopper un InkWell autour d'un widget Text et de fournir un UrlLauncher (de la bibliothèque de services) à l'attribut onTap. Installez UrlLauncher en tant que package Flutter avant de l'utiliser ci-dessous.

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('UrlLauncher'),
        ),
        body: new Center(
          child: new InkWell(
              child: new Text('Ouvrir le navigateur'),
              onTap: () => launch('https://docs.flutter.io/flutter/services/UrlLauncher-class.html')
          ),
        ),
      ),
    );
  }
}

Vous pouvez fournir un style au widget Text pour le faire ressembler à un lien.

Mettre à jour

Après avoir étudié un peu le problème, j'ai trouvé une solution différente pour implémenter les hyperliens "en ligne" que vous avez demandée. Vous pouvez utiliser le Widget RichText avec des TextSpans encapsulés.

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: 'Ce n\'est pas un lien, ',
                  style: new TextStyle(color: Colors.black),
                ),
                new TextSpan(
                  text: 'mais ceci en est un',
                  style: new TextStyle(color: Colors.blue),
                  recognizer: new TapGestureRecognizer()
                    ..onTap = () { launch('https://docs.flutter.io/flutter/services/UrlLauncher-class.html');
                  },
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

De cette manière, vous pouvez réellement mettre en évidence un mot et en faire un hyperlien ;)

15 votes

UrlLauncher ne fait plus partie de flutter, il a été déplacé vers un plugin et l'API a changé.

10 votes

Aussi, nous devons ajouter les imports: import 'package:flutter/gestures.dart'; import 'package:url_launcher/url_launcher.dart';

16 votes

Vous ne gérez pas correctement le cycle de vie de votre TapGestureRecognizer. Vous devez appeler la méthode dispose() lorsque RichText n'est plus utilisé. Voir ici: api.flutter.dev/flutter/painting/TextSpan/recognizer.html

106voto

Collin Jackson Points 29995

Flutter n'a pas de support de lien hypertexte intégré, mais vous pouvez le simuler vous-même. Il y a un exemple dans le fichier drawer.dart de la galerie. Ils utilisent un widget RichText contenant un TextSpan coloré, qui a un attribut recognizer pour gérer les clics :

        RichText(
          text: TextSpan(
            children: [
              TextSpan(
                style: bodyTextStyle,
                text: voirSourcePremier,
              ),
              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: voirSourceDeuxième,
              ),
            ],
          ),

saisissez ici la description de l'image

saisissez ici la description de l'image

0 votes

Merci. Mais ce n'est pas vraiment ce que je recherche : je cherche au-delà de la navigation dans l'application.

0 votes

Je ne suis pas sûr de ce que vous voulez dire par "regarder au-delà de la navigation dans l'application." Voulez-vous que le lien s'ouvre dans un navigateur?

0 votes

Oui, un lien ou similaire qui peut être cliqué pour s'ouvrir dans un navigateur.

84voto

CopsOnRoad Points 4705

Mise à jour (Android >= 11):

  • Configuration iOS:

    Ouvrez le fichier info.plist et ajoutez:

    LSApplicationQueriesSchemes
    
      https
  • Configuration Android:

    Ouvrez le fichier AndroidManifest.xml situé dans app/src/main et ajoutez ce qui suit à la racine:

Code Flutter:

Enveloppez simplement votre Text dans un GestureDetector ou un InkWell et gérez le clic dans onTap() en utilisant le package url_launcher.

InkWell(
  onTap: () => launchUrl(Uri.parse('https://www.google.com')),
  child: Text(
    'Cliquez ici',
    style: TextStyle(decoration: TextDecoration.underline, color: Colors.blue),
  ),
)

Capture d'écran:

Entrer la description de l'image ici

0 votes

Vous avez raison, votre solution comporte moins de lignes que les autres, mais Inkwell est le widget pour ce travail spécifique, donc au moins sémantiquement je pense que c'est la meilleure solution

3 votes

@dmarquina Oui, vous pouvez utiliser InkWell à la place de GestureDetector.

0 votes

Dans les navigateurs web, GestureDetector ne change pas le curseur et n'a pas de comportement onHover. InkWell est une meilleure solution.

7voto

bartektartanus Points 2472

Si vous voulez que cela ressemble encore plus à un lien, vous pouvez ajouter un soulignement :

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

et le résultat :

entrez la description de l'image ici

1 votes

Il n'est pas cliquable!

1 votes

Ensuite, enveloppez-le avec le widget Button. :)

7 votes

Ce n'est pas la réponse à la question, mais un commentaire à la réponse de quelqu'un. De plus, un bouton n'est pas un lien texte en ligne.

1voto

Fellipe Sanches Points 555

Une alternative (ou pas) pour mettre des liens cliquables dans votre application (pour moi, cela a juste fonctionné de cette façon) :

1 - Ajoutez le package url_launcher dans votre fichier pubspec.yaml

(la version 5.0 du package n'a pas bien fonctionné pour moi, donc j'utilise la 4.2.0+3).

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

2 - Importez-le et utilisez-le comme ci-dessous.

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('Lancer Google!',
              style: TextStyle(fontSize: 17.0)),
        ),
      ),
    );
  }

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

0 votes

Si vous avez besoin d'un lien hypertexte entre du texte, vous pouvez utiliser un FlatButton avec les mêmes couleurs de fond et de texte que le reste de vos textes, puis le formater avec TextDecoration.underline comme l'a montré bartektartanus ci-dessus...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X