I am creating a demo for RichText where I have a text and a text field,
Text widget showing a string 'Welcome to flutter' and I have a text field for input of searching word inside that string. and a button to show the search result
I have almost done with Exact word searching, But now I want to implement it should be also highlighted when the word is half entered like, 'Flut', and these 4 characters should be shown with different colors.
Widget build(BuildContext context) {
String mystring = 'Welcome to Flutter';
mywords = mystring.split(' ');
return MaterialApp(
home: Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 30.0, horizontal: 10),
child: Column(
children: [
SizedBox(
height: 20,
),
TextField(
controller: txtsearch,
),
ElevatedButton(onPressed: (){setState(() {
});}, child: Text('Search Word in String')),
SizedBox(
height: 20,
),
SizedBox(
height: 20,
),
RichText(
text: TextSpan(
style: TextStyle(fontSize: 20, color: Colors.black),
children: mywords.map((e) {
if(e!=txtsearch.text)
return TextSpan(text: e ' ');
//and suggest me is there any other way to add space instread of the way i used
else
return TextSpan(text: e ' ',style: TextStyle(
color: Colors.blue));
}).toList(),
))
],
),
),
),
);
}
CodePudding user response:
Is it important that each match is restricted to a single word, or do you actually want each substring within the entire string? If the second, you can use String.allMatches
to find the start and end indices of the matches and then construct a list of TextSpan
widgets from that. Something like this:
final search = txtsearch.text.toLowerCase();
final text = widget.text;
final matches = search.allMatches(text.toLowerCase()).toList();
final spans = <TextSpan>[];
if (matches.isEmpty) {
spans.add(TextSpan(text: text));
} else {
for (var i = 0; i < matches.length; i ) {
final strStart = i == 0 ? 0 : matches[i - 1].end;
final match = matches[i];
spans.add(
TextSpan(
text: text.substring(
strStart,
match.start,
),
),
);
spans.add(
TextSpan(
text: text.substring(
match.start,
match.end,
),
style: const TextStyle(color: Colors.blue),
),
);
}
spans.add(TextSpan(text: text.substring(matches.last.end)));
}
It's probably possible to make the loop logic a bit prettier. Working dartpad here.