I have a list of strings that loaded from json file as below:
It was getting [color="black"]dark[/color], and we weren’t [color="blue"]there[/color] yet.
They got [color="black"]there[/color] early, and they got really [color="black"]good[/color] seats.
Mr. Montoya knows the way to the [color="black"]bakery[/color] even though he's never been [color="blue"]there[/color].
How to use listview.builder to find each text that is wrap within [color="..."][/color] and add text style color or Widget to it?
For example [color="blue"]there[/color] become there (with color blue)
CodePudding user response:
Here's a working example. Not sure if it's the best way, because it's a bit hacky but gets the job done:
import 'package:flutter/material.dart';
void main() {
List<String> sentences = [
'It was getting [color="black"]dark[/color], and we weren’t [color="blue"]there[/color] yet.',
'They got [color="black"]there[/color] early, and they got really [color="black"]good[/color] seats.',
'''Mr. Montoya knows the way to the [color="black"]bakery[/color] even though he's never been [color="blue"]there[/color].'''
];
runApp(MaterialApp(
home: Scaffold(
body: ListView.builder(
itemCount: sentences.length,
itemBuilder: (context, index) =>
Padding(
padding: const EdgeInsets.all(8.0),
child: TextWithColors(text: sentences[index]),
)),
)));
}
class TextWithColors extends StatelessWidget {
final String text;
static final regex = RegExp("(?=\\[)|(?<=\\])");
const TextWithColors({Key? key, required this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
final split = text.split(regex);
Color currentColor = Colors.grey;
return RichText(
text: TextSpan(
children: <InlineSpan>[
for (String text in split)
text.startsWith('[')
? TextSpan(
style: TextStyle(
color: currentColor = text.contains('"black"')
? Colors.black
: text.contains('"blue"')
? Colors.blue
: Colors.grey))
: TextSpan(text: text, style: TextStyle(color: currentColor)),
],
));
}
}
Output:
CodePudding user response:
You need to use regular expression that will change your strings into multiple TextSpan's that you can combine. so your [color=black]black[/color]
will become
TextSpan(text: 'black', style: const TextStyle(color: Colors.black))
I took it from other stackoverflow question
You should use the RichText widget.
A RichText widget will take in a TextSpan widget that can also have a list of children TextSpans.
Each TextSpan widget can have a different TextStyle.
Here is the example code to render: Hello World
var text = RichText( text: TextSpan( // Note: Styles for TextSpans must be explicitly defined. // Child text spans will inherit styles from parent style: const TextStyle( fontSize: 14.0, color: Colors.black, ), children: <TextSpan>[ TextSpan(text: 'Hello'), TextSpan(text: 'World', style: const TextStyle(fontWeight: FontWeight.bold)), ], ), );