skip to Main Content

I’m making a Flutter UI for a grammar checking tool.

I know we could use RichText to make text that has whatever style we want and can be clicked. I also know how to set textStyles and use GestureDetector.

However, the user needs to the ability to freely edit the text as a normal text input.

Desired functionality

How can we do this in Flutter? Any widgets to the rescue?

2

Answers


  1. a) For underline you can use a property of TextStyle. Example:

    style: TextStyle(decoration: TextDecoration.underline)
    

    b) For make clickable, I think you have to use GestureDetector() apli.flutter.dev

    Login or Signup to reply.
  2. You can do this by extending TextEditingController and override buildTextSpan method with your own logic to add underline under specific words. One way is to use regex. Here is an example.
    import ‘package:flutter/material.dart’;

    class MyTextEditingController extends TextEditingController {
      @override
      TextSpan buildTextSpan({
        required BuildContext context,
        TextStyle? style,
        required bool withComposing,
      }) {
        final List<InlineSpan> textSpanChildren = <InlineSpan>[];
    
        text.splitMapJoin(RegExp('underline'), onMatch: (m) {
          final String? textPart = m.group(0);
    
          if (textPart == null) return '';
          print(textPart);
          TextStyle underLineStyle = style ?? const TextStyle();
          TextStyle mergeWith =  const TextStyle(
              decoration: TextDecoration.underline,
              decorationColor: Colors.red,
              decorationThickness: 2,
              decorationStyle: TextDecorationStyle.wavy);
       
              print(underLineStyle.decoration);
          textSpanChildren.add(TextSpan(text: textPart, style: underLineStyle.merge(mergeWith)));
    
          return '';
        }, onNonMatch: (text) {
          textSpanChildren.add(TextSpan(text: text, style: style));
    
          return '';
        });
        return TextSpan(style: style, children: textSpanChildren);
      }
    }
    

    Once this is done, use your newly created Controller instead of TextEditingController with TextFeild.

    class MyHomePage extends StatelessWidget {
         final MyTextEditingController textEditingController =
           MyTextEditingController();
    
      @override
      Widget build(BuildContext context) {
      
    
        return Scaffold(
          body: Center(
            child: Padding(
              padding: const EdgeInsets.all(15),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  TextField(
                     decoration: InputDecoration(
        filled: true,
        hoverColor: Colors.blue.shade100,
        border: OutlineInputBorder(),
      ),
                
                    controller: textEditingController,
         
                    style: TextStyle(color: Colors.black),
                  
      
                  ),
              
                ],
              ),
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search