Is there a way to take input in multiple text styles in a textfield in Flutter like this?
Where the user can select a part of the text and edit its style like he wants
You can try use RichText
RichText(
text: TextSpan(
text: 'Hello ',
style: DefaultTextStyle.of(context).style,
children: const <TextSpan>[
TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ' world!'),
],
),
)
Source: Source on api.flutter.dev
If you want a TextField with multiple text styles, it is actually pretty easy to set up: You first need to create a custom TextEditingController. You extend TextEditingController and override the buildTextSpan() method:
class MultiStyleTextEditingController extends TextEditingController {
@override
TextSpan buildTextSpan(
{required BuildContext context,
TextStyle? style,
required bool withComposing}) {
// Let's break our text into blocks divided by spaces
final words = text.split(' ');
final textSpanChildren = <TextSpan>[];
// Add your text styling rules
for (final word in words) {
TextStyle wordStyle;
if (word == 'blue') {
wordStyle = TextStyle(color: Colors.blue);
} else if (word == 'italic') {
wordStyle = TextStyle(color: Colors.black, fontStyle: FontStyle.italic);
} else {
wordStyle = TextStyle(color: Colors.black);
}
final child = TextSpan(text: word, style: wordStyle);
textSpanChildren.add(child);
// Add the space back in
textSpanChildren.add(TextSpan(text: ' '));
}
return TextSpan(children: textSpanChildren);
}
}
Now just add this controller to your TextField:
TextField(
controller: MultiStyleTextEditingController()
..text = "This is blue text and this is italic",
);
That's it! The word blue and the word italic will have custom styling.
text or value property in the MultiStyleTextEditingController somewhere else in your code, causing it to change when the keyboard closes.You can use this https://pub.dev/packages/flutter_social_textfield. You can add different styles too.
I made a Flutter package that might help with this question called fxf.
To create the text you've written above, you can do the following:
import 'package:fxf/fxf.dart' as fxf;
class MyWidget extends StatelessWidget {
...
final String text = '''
~(0xff7c65c4)!(3,0,0xff7c65c4)Same!(d)~(d)
*(5)!(1,0,0xffff0000)textfield!(d)*(d)
`(1)different`(d)
~(0xffe787cc)!(1,0,0xffe787cc)styles!(d)~(d)
''';
Widget build(BuildContext context) {
return Center(
child: fxf.Text(text),
);
}
}
Which produces the following result: image of text with multiple styles
For example, on line ~(0xff7c65c4)!(3,0,0xff7c65c4)Same!(d)~(d), style command ~(0xff7c65c4)
changes the text color to a light purple, while ~(d) returns the text back to its default black color. Likewise, !(3,0,0xff7c65c4) adds a
strikethrough solid line with the same purple color, and !(d) removes it.
More info on the style commands can be found on the fxf readme.