I want to display following text on screen with superscripts being displayed properly. How to do that in flutter?
You can use RichText and Unicode
final defaultStyle = TextStyle(color: Colors.black);
final blueStyle = TextStyle(color: Colors.blue);
return Center(
child: RichText(
text: TextSpan(
text: "c. 10\u{207B}\u{2076} seconds: ",
style: defaultStyle,
children: [
TextSpan(text: "Hadron epoch ", style: blueStyle, children: [
TextSpan(
style: defaultStyle,
text:
"begins: As the universe cools to about 10\u{00B9}\u{2070} kelvin,",
),
])
]),
),
);
More info: https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts
Related
I want to set 'vertical-align: super' on TextSpan.
I want the result like this:
Another answer used Unicode superscript characters but not all characters have superscript version. In that case you can use WidgetSpan together with Transform.translate. You'll have to tweak fontSize and y-offset until it fits your layout.
RichText(
text: TextSpan(
children: [
TextSpan(text: 'Usage (m'),
WidgetSpan(
child: Transform.translate(
offset: const Offset(0.0, -7.0),
child: Text(
'3',
style: TextStyle(fontSize: 10),
),
),
),
TextSpan(text: ')'),
],
),
)
Linked answers use Row and Text widgets to achieve this effect but I needed to use RichText. One way to achieve this is to use Unicode superscript characters:
https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts
Example code:
RichText(
text: TextSpan(
children: [
TextSpan(text: 'Usage (m'),
TextSpan(text: '³'),
TextSpan(text: ')'),
],
),
)
I am using RichText and in this
text justify is not working correctly with RichText when using any of text span with style decoration: TextDecoration.underline
RichText(
softWrap: true,
textAlign: TextAlign.justify,
text: TextSpan(
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w500,
fontSize: 16.0,
),
children: getSpan(),
),
)
List<TextSpan> getSpan() {
List<TextSpan> spans = List<TextSpan>();
spans.add(TextSpan(
text:
"And thus We made them rise ",
));
spans.add(
TextSpan(
text: " they ",
style: TextStyle(
decoration: TextDecoration.underline,
),
recognizer: TapGestureRecognizer()
..onTap = () {
print("click on me");
}),
);
spans.add(TextSpan(
text:
" And thus We made them rise ",
));
return spans;
}
It looks like a nasty effect of textAlign property when set to TextAlign.justify.
RichText(
softWrap: true,
//textAlign: TextAlign.justify,
text: TextSpan(
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w500,
fontSize: 16.0,
),
children: getSpan(),
),
)
Updated to 21/03/19
The bug it is now fixed and at the moment (21/03/19) it is available in the master flutter channel:
flutter channel master
How to apply different styles for different part of displayed text. How to do this in flutter?
Example:
Hello World
This can be achieved using RichText
RichText(
text: TextSpan(
text: 'Hello',
style: TextStyle(fontSize: 22, color: Colors.black),
children: <TextSpan>[
TextSpan(
text: 'World',
style: TextStyle(
fontSize: 24,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
),
),
]
),
),
return RichText(
text: TextSpan(
text: 'Can you ',
style: TextStyle(color: Colors.black),
children: <TextSpan>[
TextSpan(
text: 'find the',
style: TextStyle(
color: Colors.green,
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.wavy,
),
recognizer: _longPressRecognizer,
),
TextSpan(text: 'secret?'),
],
),
);
I have a RichText with some TextSpan. I want one of the TextSpan widgets to have a background on it so I used background: Paint()..color = Colors.redAccent as its text style.
Is there a way to add some extra red space/padding to the background.
This is how it currently looks:
This is how I want it to look (notice the extra red on the top and bottom of the highlighted text):
This is the code used:
Scaffold(
appBar: new AppBar(),
body: new RichText(
text: new TextSpan(
text: 'This is a one the lines in the span \n ',
style: TextStyle(fontSize: 15.0, color: Colors.black),
children: <TextSpan>[
new TextSpan(
text: 'This is the second line',
style: new TextStyle(fontWeight: FontWeight.bold)),
new TextSpan(
text: ' background on me ',
style: new TextStyle(
fontWeight: FontWeight.bold,
background: Paint()..color = Colors.redAccent,
)),
new TextSpan(text: ' This is another of the lines in the span!'),
],
),
), // This trailing comma makes auto-formatting nicer for build methods.
)
I tried adding height to the text style, but it doesn't affect the height of the background.
The new solution in 2019 with flutter 1.7.8 is WidgetSpan, you could just add a Container and a Padding or any combination of widget to make more variety!
Here is an example to use on the case:
WidgetSpan(
child: Container(
color: Colors.red,
padding: EdgeInsets.all(8.0),
child: Text("background on me", style: ...),
)
)
And don't forget to change <TextSpan>[] to <InlineSpan>[], that's It!
Quite ugly solution, but I haven't found other (
TextStyle(fontWeight: FontWeight.bold,
background: Paint()..color = Colors.redAccent
..strokeWidth = 16.5
..style = PaintingStyle.stroke,)
strokeWidth have to be big enough to cover height of text. In my case 16.5 is minimal suitable value
you can use widgetSpan that inside RichText so that you can add any widget inside RichText.
RichText(
maxLines: 1,
overflow: TextOverflow.ellipsis,
text: TextSpan(
text: "text one", // text of exemple
children: [
// add a space between texts
WidgetSpan(
child: Padding(
padding: const EdgeInsets.only(left: 10.0),
),
),
TextSpan(
text: "text two", // text exemple
),
],
),
),
How can I have a line of text with different formatting?
e.g.:
Hello World
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)),
],
),
);
[UPDATE]
The below answer fits best for couple of words and not for a paragraph,If you have a long sentence or a paragraph where you need to format a particular text prefer using RichText as suggested by #DvdWasibi in the above answer
[OLD ANSWER]
I like keeping my code short and clean this is How I Would do it add two text fields in a row one with Normal font and another bold,
Note: This may not look good for a long paragraph looks good for Headlines etc.
Row(children: [
Text("Hello"),
Text("World", style: const TextStyle(fontWeight: FontWeight.bold))
]);
and you should get a desired output as "Hello World"
return RichText(
text: TextSpan(
text: 'Can you ',
style: TextStyle(color: Colors.black),
children: <TextSpan>[
TextSpan(
text: 'find the',
style: TextStyle(
color: Colors.green,
decoration: TextDecoration.underline,
decorationStyle: TextDecorationStyle.wavy,
),
recognizer: _longPressRecognizer,
),
TextSpan(text: 'secret?'),
],
),
);
You should use the Text.rich constructor from Text class here.
By using the rich constructor you can display a paragraph with differently styled TextSpans.
Why I recommended it instead of RichText is because of by using RichText you will required to define the parent TextStyle in RichText but using the rich constructor of Text you don't need explicitly defined the parent TextStyle in Text.rich
Here is the example how to use it with same result
Using RichText
const text = RichText(
text: TextSpan(
// Here is the explicit parent TextStyle
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
fontFamily: 'Montserrat',
),
children: <TextSpan>[
new TextSpan(text: 'Hello'),
new TextSpan(text: 'World', style: new TextStyle(fontWeight: FontWeight.bold)),
],
),
);
Using rich constructor of Text
const text = Text.rich(
TextSpan(
// with no TextStyle it will have default text style
text: 'Hello',
children: <TextSpan>[
TextSpan(text: 'World', style: TextStyle(fontWeight: FontWeight.bold)),
],
),
)
I've solved a similar problem by using flutter_html widget with custom styles for different tags.
Actually, I've got the strings in different languages and some parts of them should be bold, so it wasn't easy to determine which part of the string I should make bold since strings was in l10n locale files. Here is example:
Container(
child: Html(
data: "<p>My normal text <b>with bold part</b> in any place</p>",
style: {
"p": Style(
fontSize: FontSize.large,
fontWeight: FontWeight.normal),
"b": Style(
fontWeight: FontWeight.bold,
),
)
);
I think this approach is useful in case you have a lot of differently styled text inside your regular text.
Regex
You can use this widget. The example below always make numbers bold.
import 'package:flutter/material.dart';
class TextBold extends StatelessWidget{
final String text;
final String regex;
static const _separator = " ";
const TextBold({Key key, this.text, this.regex = r'\d+'}) : super(key: key);
#override
Widget build(BuildContext context) {
final parts = splitJoin();
return Text.rich(TextSpan(
children: parts.map((e) => TextSpan(
text: e.text,
style: (e.isBold)
? const TextStyle(fontFamily: 'bold')
: const TextStyle(fontFamily: 'light')))
.toList()));
}
// Splits text using separator, tag ones to be bold using regex
// and rejoin equal parts back when possible
List<TextPart> splitJoin(){
assert(text!=null);
final tmp = <TextPart>[];
final parts = text.split(_separator);
// Bold it
for (final p in parts){
tmp.add(TextPart(p + _separator,p.contains(RegExp(regex))));
}
final result = <TextPart>[tmp[0]];
// Fold it
if (tmp.length>1) {
int resultIdx = 0;
for (int i = 1; i < tmp.length; i++)
if (tmp[i - 1].isBold != tmp[i].isBold) {
result.add(tmp[i]);
resultIdx++;
}
else
result[resultIdx].text = result[resultIdx].text
+ tmp[i].text;
}
return result;
}
}
class TextPart{
String text;
bool isBold;
TextPart(this.text, this.isBold);
}
Not fully tested but you can try this helper function that uses Text.rich and takes in the fullText and the textToBold then returns a Text:
static Text boldTextPortion(
String fullText,
String textToBold,
) {
final texts = fullText.split(textToBold);
final textSpans = List.empty(growable: true);
texts.asMap().forEach((index, value) {
textSpans.add(TextSpan(text: value));
if (index < (texts.length - 1)) {
textSpans.add(TextSpan(
text: textToBold,
style: const TextStyle(fontWeight: FontWeight.bold),
));
}
});
return Text.rich(
TextSpan(
children: <TextSpan>[...textSpans],
),
);
}
RichText()
Or if you receiving text from for example 'someText'.tr,
so use styled_text pub package.