Home > Software design >  Make random parts of a text clickable without textSpan in flutter
Make random parts of a text clickable without textSpan in flutter

Time:08-26

Make random parts of a text clickable in flutter without textSpan because when I change the language the order of words also changes. For the textSpan, we know the order of texts matters.

I have user agreement text below in Turkish and Kyrgyz languages. If Locale is in Turkish, Turkish user agreement should be visible, otherwise, Kyrgyz user agreement.

Sample texts:

  1. Кирүүнү басуу менен мен Тейлөө шарттарына макулмун.
  2. Enter'a tıklayarak Hizmet Şartlarını kabul ediyorum

CodePudding user response:

The way I would do it is to somehow mark the clickable part, for example by enclosing it in {}. You can then do this for example:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
      home: Column(
    children: const [
      TextWithLink(
          text: "Кирүүнү басуу менен мен {Тейлөө шарттарына макулмун}"),
      TextWithLink(
          text: "Enter'a tıklayarak {Hizmet Şartlarını} kabul ediyorum")
    ],
  )));
}

class TextWithLink extends StatelessWidget {
  final String text;
  static final regex = RegExp("(?={)|(?<=})");

  const TextWithLink({Key? key, required this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final split = text.split(regex);
    return RichText(
        text: TextSpan(
      children: <InlineSpan>[
        for (String text in split)
          text.startsWith('{')
              ? TextSpan(
                  text: text.substring(1, text.length - 1),
                  style: const TextStyle(
                      decoration: TextDecoration.underline, color: Colors.blue),
                  recognizer: TapGestureRecognizer()
                    ..onTap = () => print("click"),
                )
              : TextSpan(text: text),
      ],
    ));
  }
}

Output:

enter image description here

CodePudding user response:

Use RichText with TextSpan and GestureRecognizer. With GestureRecognizer you can detect tap, double tap, long press and etc.

Widget build(BuildContext context) {
    TextStyle defaultStyle = TextStyle(color: Colors.grey, fontSize: 20.0);
    TextStyle linkStyle = TextStyle(color: Colors.blue);
    return RichText(
      text: TextSpan(
        style: defaultStyle,
        children: <TextSpan>[
          TextSpan(text: 'By clicking Sign Up, you agree to our '),
          TextSpan(
              text: 'Terms of Service',
              style: linkStyle,
              recognizer: TapGestureRecognizer()
                ..onTap = () {
                  print('Terms of Service"');
                }),
          TextSpan(text: ' and that you have read our '),
          TextSpan(
              text: 'Privacy Policy',
              style: linkStyle,
              recognizer: TapGestureRecognizer()
                ..onTap = () {
                  print('Privacy Policy"');
                }),
        ],
      ),
    );
  }
  • Related