selectable_autolink_text 2.6.0 copy "selectable_autolink_text: ^2.6.0" to clipboard
selectable_autolink_text: ^2.6.0 copied to clipboard

Generate inline links that can be selected and tapped in text for Flutter.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:selectable_autolink_text/selectable_autolink_text.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';

void main() => runApp(_MyApp());

class _MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
        scaffoldBackgroundColor: Colors.white,
      ),
      home: _MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class _MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Selectable Autolink Text')),
      body: SafeArea(
        child: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            _basic(context),
            const Divider(height: 32),
            _advanced(context),
            const Divider(height: 32),
            _custom(context),
            const Divider(height: 32),
            _moreAdvanced(context),
          ],
        ),
      ),
    );
  }

  Widget _basic(BuildContext context) {
    return SelectableAutoLinkText(
      'Basic\n'
      'Generate inline links that can be selected, tapped, '
      'long pressed and highlighted on tap.\n'
      'As written below.\n'
      'Dart packages https://pub.dev',
      linkStyle: const TextStyle(color: Colors.blueAccent),
      highlightedLinkStyle: TextStyle(
        color: Colors.blueAccent,
        backgroundColor: Colors.blueAccent.withAlpha(0x33),
      ),
      onTap: _launchUrl,
      onLongPress: _share,
      contextMenuBuilder: (context, state) {
        return AdaptiveTextSelectionToolbar.buttonItems(
          buttonItems: state.contextMenuButtonItems
            ..add(ContextMenuButtonItem(
              label: 'Print',
              onPressed: () {
                final v = state.currentTextEditingValue;
                print(
                    '☕️ ${v.text.substring(v.selection.start, v.selection.end)}');
              },
            )),
          anchors: state.contextMenuAnchors,
        );
      },
    );
  }

  Widget _advanced(BuildContext context) {
    return SelectableAutoLinkText(
      '''
Advanced
You can shrink url like https://github.com/miyakeryo/flutter_selectable_autolink_text
tel: 012-3456-7890
email: mail@example.com''',
      style: TextStyle(color: Colors.green[800]),
      linkStyle: const TextStyle(color: Colors.purpleAccent),
      highlightedLinkStyle: TextStyle(
        color: Colors.purpleAccent,
        backgroundColor: Colors.purpleAccent.withAlpha(0x33),
      ),
      onTransformDisplayLink: AutoLinkUtils.shrinkUrl,
      onTap: (url) async {
        print('🌶 Tap: $url');
        if (!await _launchUrl(url)) {
          _alert(context, '🌶 Tap', url);
        }
      },
      onLongPress: (url) {
        print('🍔 LongPress: $url');
        _share(url);
      },
      onTapOther: (local, global) {
        print('🍇️ onTapOther: $local, $global');
      },
      onLongPressOther: (local, global) {
        print('🍊️ onLongPressOther: $local, $global');
      },
    );
  }

  Widget _custom(BuildContext context) {
    return SelectableAutoLinkText(
      'Custom links'
      '\nHi! @screen_name.'
      ' If you customize the regular expression, you can make them.'
      ' #hash_tag',
      style: const TextStyle(color: Colors.black87),
      linkStyle: const TextStyle(color: Colors.deepOrangeAccent),
      highlightedLinkStyle: TextStyle(
        color: Colors.deepOrangeAccent,
        backgroundColor: Colors.deepOrangeAccent.withAlpha(0x33),
      ),
      linkRegExpPattern: '(@[\\w]+|#[\\w]+|${AutoLinkUtils.urlRegExpPattern})',
      onTransformDisplayLink: AutoLinkUtils.shrinkUrl,
      onTap: (url) => _alert(context, '🍒 Tap', url),
      onLongPress: (url) => _alert(context, '🍩 LongPress', url),
      onDebugMatch: (match) {
        /// for debug
        print('DebugMatch:[${match.start}-${match.end}]`${match.group(0)}`');
      },
    );
  }

  Widget _moreAdvanced(BuildContext context) {
    final blueStyle = const TextStyle(color: Colors.blueAccent);
    final highlightedStyle = TextStyle(
      color: Colors.blueAccent,
      backgroundColor: Colors.blueAccent.withAlpha(0x33),
    );
    final orangeStyle = TextStyle(color: Colors.orange);
    final boldStyle = const TextStyle(fontWeight: FontWeight.bold);
    final italicStyle = const TextStyle(fontStyle: FontStyle.italic);
    final bigStyle = const TextStyle(fontSize: 24);
    final regExpPattern = r'\[([^\]]+)\]\(([^\s\)]+)\)';
    final regExp = RegExp(regExpPattern);

    return SelectableAutoLinkText(
      '''
More advanced usage

[This is a link text](https://google.com)
[This text is bold](bold)
This text is normal
[This text is italic](italic)
[This text is orange](orange)
[This text is big](big)''',
      linkRegExpPattern: regExpPattern,
      onTransformDisplayLink: (s) {
        final match = regExp.firstMatch(s);
        if (match != null && match.groupCount == 2) {
          final text1 = match.group(1)!;
          final text2 = match.group(2)!;
          switch (text2) {
            case 'bold':
              return LinkAttribute(text1, style: boldStyle);
            case 'italic':
              return LinkAttribute(text1, style: italicStyle);
            case 'orange':
              return LinkAttribute(text1, style: orangeStyle);
            case 'big':
              return LinkAttribute(text1, style: bigStyle);
            default:
              if (text2.startsWith('http')) {
                return LinkAttribute(
                  text1,
                  link: text2,
                  style: blueStyle,
                  highlightedStyle: highlightedStyle,
                );
              } else {
                return LinkAttribute(text1);
              }
          }
        }
        return LinkAttribute(s);
      },
      onTap: _launchUrl,
      onLongPress: _share,
    );
  }

  Future<bool> _launchUrl(String url) async {
    final uri = Uri.parse(url);
    if (await canLaunchUrl(uri)) {
      return await launchUrl(uri);
    } else {
      return false;
    }
  }

  Future _share(String text, [String? subject]) async {
    try {
      return await Share.share(text, subject: subject);
    } on MissingPluginException catch (e) {
      print("😡 $e");
    }
  }

  Future _alert(BuildContext context, String title, [String? message]) {
    return showDialog(
      context: context,
      builder: (c) {
        return AlertDialog(
          title: Text(title),
          content: message != null ? Text(message) : null,
          actions: [
            TextButton(
              child: const Text('Close'),
              onPressed: Navigator.of(c).pop,
            ),
          ],
        );
      },
    );
  }
}
80
likes
140
points
4.14k
downloads

Publisher

verified publishermiyake.id

Weekly Downloads

Generate inline links that can be selected and tapped in text for Flutter.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on selectable_autolink_text