Highlight And UnderLine text in different colors - TextField in Flutter

57 Views Asked by At

How to create underlines for parts of text in textfield using offset , i can replace the mistake word with correct word but i can't change style of this is word to notify user that it's error.

I Can use the buildTextSpan Method but it's not working with me.

Code of replacement

the result which i want to get

1

There are 1 best solutions below

0
Dhafin Rayhan On BEST ANSWER

The idea is to use a custom TextEditingController that overrides the buildTextSpan method. You can then return your own TextSpan that uses different styles for parts of the text.

Here's just a minimal example of how you can achieve that. Be aware that there might be some other aspects from the original buildTextSpan that you need to implement in the overriding method as well.

class HighlightRange {
  final int start;
  final int end;
  final Color color;

  HighlightRange({required this.start, required this.end, required this.color});
}

class CustomTextEditingController extends TextEditingController {
  // Hardcoded example; in real usage you should initialize it with
  // empty list and set the list through the controller instance
  List<HighlightRange> ranges = [
    HighlightRange(start: 11, end: 18, color: Colors.orange),
    HighlightRange(start: 31, end: 42, color: Colors.green),
  ];

  TextStyle _getHighlightStyle(HighlightRange range) {
    return TextStyle(
      decoration: TextDecoration.underline,
      decorationColor: range.color,
    );
  }

  @override
  TextSpan buildTextSpan({
    required BuildContext context,
    TextStyle? style,
    required bool withComposing,
  }) {
    List<InlineSpan> children;

    if (ranges.isEmpty) {
      children = [TextSpan(text: text)];
    } else {
      children = [
        TextSpan(text: text.substring(0, ranges.first.start)),
        TextSpan(
          text: text.substring(ranges.first.start, ranges.first.end),
          style: _getHighlightStyle(ranges.first),
        ),
      ];

      for (int i = 1; i < ranges.length; i++) {
        children.addAll([
          TextSpan(text: text.substring(ranges[i - 1].end, ranges[i].start)),
          TextSpan(
            text: text.substring(ranges[i].start, ranges[i].end),
            style: _getHighlightStyle(ranges[i]),
          ),
        ]);
      }

      children.add(TextSpan(text: text.substring(ranges.last.end)));
    }

    return TextSpan(
      style: TextStyle(color: Colors.black),
      children: children,
    );
  }
}

Define the controller with the custom controller class in the state of your StatefulWidget:

final controller = CustomTextEditingController();

You can access the ranges property:

controller.ranges = // Do something with it

Result