Skip to content

A Flutter plugin used to detect links in texts using NSDataDetector on iOS and TextClassifier on Android

License

Notifications You must be signed in to change notification settings

developerjamiu/smart-text-flutter

Repository files navigation

Smart Text Flutter

A Flutter plugin used to find links in plain texts.

Android iOS
Support SDK 19+ 11.0+

It uses NSDataDetector for iOS and TextClassifier for Android.

Texts (links) can be among these 6 types

enum ItemSpanType { address, phone, email, datetime, url, text }

Usage

To use this plugin, add smart_text_flutter as a dependency in your pubspec.yaml file.

Example

class SmartTextFlutterExample extends StatelessWidget {
  const SmartTextFlutterExample({super.key});

  @override
  Widget build(BuildContext context) {
    const text =
        'Here is a text with an address: 36 Lagos Street written at 9 PM by someone with phone: +2340000000000 and you can reach him at reaching@email.com or you can check twitter.com';

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Smart Text Flutter'),
        ),
        body: const Center(
          child: SmartText(text),
        ),
      ),
    );
  }
}

Demo

ScreenRecording2024-03-12at17 38 55-ezgif com-resize

Notes

  • DateTime is not supported on Android
  • Address is not supported on Android 8.1 (API 27) and below
  • There is no default implementation for when DateTime is clicked (the formatted date returned in the callback in case)

Properties

  /// The text to linkify
  /// This text will be classified and the links will be highlighted
  final String text;

  /// The configuration for setting the [TextStyle] and onClicked method
  /// This affects the whole text
  final ItemSpanConfig? config;

  /// The configuration for setting the [TextStyle] and what happens when the address link is clicked
  final ItemSpanConfig? addressConfig;

  /// The configuration for setting the [TextStyle] and what happens when the phone link is clicked
  final ItemSpanConfig? phoneConfig;

  /// The configuration for setting the [TextStyle] and what happens when the url is clicked
  final ItemSpanConfig? urlConfig;

  /// The configuration for setting the [TextStyle] and what happens when the date time is clicked
  final ItemSpanConfig? dateTimeConfig;

  /// The configuration for setting the [TextStyle] and what happens when the email link is clicked
  final ItemSpanConfig? emailConfig;

ItemSpanConfig

  /// The [TextStyle] if the link
  final TextStyle? textStyle;

  /// The method called when a link is clicked
  /// When the is set, the implementation will override the default
  /// implementation
  final void Function(String data)? onClicked;

The smart text widget example

  SmartText(
    text,
    config: const ItemSpanConfig(
      textStyle: TextStyle(),
    ),
    addressConfig: ItemSpanConfig(
      textStyle: const TextStyle(),
      onClicked: (_) {},
    ),
    emailConfig: ItemSpanConfig(
      textStyle: const TextStyle(),
      onClicked: (_) {},
    ),
    phoneConfig: ItemSpanConfig(
      textStyle: const TextStyle(),
      onClicked: (_) {},
    ),
    urlConfig: ItemSpanConfig(
      textStyle: const TextStyle(),
      onClicked: (_) {},
    ),
    dateTimeConfig: ItemSpanConfig(
      textStyle: const TextStyle(),
      onClicked: (_) {},
    ),
  )

Code from the example folder.

class SmartTextFlutterExample extends StatefulWidget {
  const SmartTextFlutterExample({super.key});

  @override
  State<SmartTextFlutterExample> createState() =>
      _SmartTextFlutterExampleState();
}

class _SmartTextFlutterExampleState extends State<SmartTextFlutterExample> {
  final List<String> messageTexts = [];

  late final _messageController = TextEditingController();

  @override
  void dispose() {
    _messageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Smart Text Flutter'),
        ),
        body: Column(
          children: [
            Expanded(
              child: ListView.builder(
                itemCount: messageTexts.length,
                itemBuilder: (context, index) => Align(
                  alignment: Alignment.centerLeft,
                  child: Container(
                    constraints: BoxConstraints(
                      maxWidth: MediaQuery.sizeOf(context).width * 0.8,
                    ),
                    decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(16),
                      color: Colors.blueGrey.shade50,
                    ),
                    padding: const EdgeInsets.all(8),
                    margin: const EdgeInsets.all(8),
                    child: SmartText(
                      messageTexts[index],
                    ),
                  ),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                children: [
                  Expanded(
                    child: TextField(
                      controller: _messageController,
                      decoration: const InputDecoration(
                        hintText: 'Enter text',
                        contentPadding: EdgeInsets.all(8),
                        border: OutlineInputBorder(),
                      ),
                    ),
                  ),
                  const SizedBox(width: 8),
                  ElevatedButton(
                    onPressed: () {
                      setState(() => messageTexts.add(_messageController.text));
                      _messageController.clear();
                    },
                    child: const Text('Send Message'),
                  ),
                ],
              ),
            ),
            const SizedBox(height: 40),
          ],
        ),
      ),
    );
  }
}

Bugs/Requests

If you encounter any problems feel free to open an issue here. If you feel the library is missing a feature, please raise a ticket on GitHub and I'll look into it. Pull requests are also welcome.

About

A Flutter plugin used to detect links in texts using NSDataDetector on iOS and TextClassifier on Android

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published