wcjord
wcjord

Reputation: 539

How to a) underline and b) make clickable parts of editable text in input field?

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?

Upvotes: 0

Views: 220

Answers (2)

Lala Iqbal
Lala Iqbal

Reputation: 51

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),
              
  
              ),
          
            ],
          ),
        ),
      ),
    );
  }
}

Upvotes: 2

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

Upvotes: -1

Related Questions