How I use 'vertical-align: super' in TextSpan - dart

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: ')'),
],
),
)

Related

How to format text to be displayed in Flutter

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

Adding extra padding to TextSpan background in RichText widget

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
),
],
),
),

Flutter- wrapping text [duplicate]

This question already has answers here:
Flutter - Wrap text on overflow, like insert ellipsis or fade
(23 answers)
Closed 3 years ago.
I want wrap text as text grows. I searched through and tried wrap with almost everything but still text stays one line and overflows from the screen.
Does anyone know how to achieve this?
Any help is highly appreciated!
Positioned(
left: position.dx,
top: position.dy,
child: new Draggable(
data: widget.index,
onDragStarted: widget.setDragging,
onDraggableCanceled: (velocity, offset) {
setState(() {
position = offset;
widget.secondCallback(offset, widget.index);
widget.endDragging();
});
},
child: new GestureDetector(
onTap: () {
widget.callback(widget.caption, widget.index);
},
child: new Text(
widget.caption.caption,
style: new TextStyle(
color: widget.caption.color,
fontSize: widget.caption.fontSize,
),
),
),
feedback: new Material(
type: MaterialType.transparency,
child: new Text(
widget.caption.caption,
style: new TextStyle(
color: widget.caption.color,
fontSize: widget.caption.fontSize),
softWrap: true,
),
),
));
The Flexible does the trick
new Container(
child: Row(
children: <Widget>[
Flexible(
child: new Text("A looooooooooooooooooong text"))
],
));
This is the official doc https://flutter.dev/docs/development/ui/layout#lay-out-multiple-widgets-vertically-and-horizontally on how to arrange widgets.
Remember that Flexible and also Expanded, should only be used within a Column, Row or Flex, because of the Incorrect use of ParentDataWidget.
The solution is not the mere Flexible
In a project of mine I wrap Text instances around Containers. This particular code sample features two stacked Text objects.
Here's a code sample.
//80% of screen width
double c_width = MediaQuery.of(context).size.width*0.8;
return new Container (
padding: const EdgeInsets.all(16.0),
width: c_width,
child: new Column (
children: <Widget>[
new Text ("Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 Long text 1 ", textAlign: TextAlign.left),
new Text ("Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2, Long Text 2", textAlign: TextAlign.left),
],
),
);
[edit] Added a width constraint to the container
Using Ellipsis
Text(
"This is a long text",
overflow: TextOverflow.ellipsis,
),
Using Fade
Text(
"This is a long text",
overflow: TextOverflow.fade,
maxLines: 1,
softWrap: false,
),
Using Clip
Text(
"This is a long text",
overflow: TextOverflow.clip,
maxLines: 1,
softWrap: false,
),
Note:
If you are using Text inside a Row, you can put above Text inside Expanded like:
Expanded(
child: AboveText(),
)
Use Expanded
Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(_name, style: Theme.of(context).textTheme.subhead),
new Container(
margin: const EdgeInsets.only(top: 5.0),
child: new Text(text),
),
],
),
If it's a single text widget that you want to wrap, you can either use Flexible or Expanded widgets.
Expanded(
child: Text('Some lengthy text for testing'),
)
or
Flexible(
child: Text('Some lengthy text for testing'),
)
For multiple widgets, you may choose Wrap widget. For further details checkout this
Try Wrap widget to wrap text as text grows:
Example:
Wrap(
direction: Axis.vertical, //Vertical || Horizontal
children: <Widget>[
Text(
'Your Text',
style: TextStyle(fontSize: 30),
),
Text(
'Your Text',
style: TextStyle(fontSize: 30),
),
],
),
You Can Wrap your widget with Flexible Widget and than you can set property of Text using overflow property of Text Widget.
you have to set TextOverflow.clip
for example:-
Flexible
(child: new Text("This is Dummy Long Text",
style: TextStyle(
fontFamily: "Roboto",
color: Colors.black,
fontSize: 10.0,
fontWeight: FontWeight.bold),
overflow: TextOverflow.clip,),)
hope this help someone :)
Container(
color: Color.fromRGBO(224, 251, 253, 1.0),
child: ListTile(
dense: true,
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
RichText(
textAlign: TextAlign.left,
softWrap: true,
text: TextSpan(children: <TextSpan>
[
TextSpan(text: "hello: ",
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.bold)),
TextSpan(text: "I hope this helps",
style: TextStyle(color: Colors.black)),
]
),
),
],
),
),
),
You can use Flexible, in this case the person.name could be a long name (Labels and BlankSpace are custom classes that return widgets) :
new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Flexible(
child: Labels.getTitle_2(person.name,
color: StyleColors.COLOR_BLACK)),
BlankSpace.column(3),
Labels.getTitle_1(person.likes())
]),
BlankSpace.row(3),
Labels.getTitle_2(person.shortDescription),
],
)

Flutter textfield that auto expands when text is entered and then starts scrolling the text when a certain height is reached

I've tried many configurations of the Flutter TextField but can't figure out how to build this one.
I'm looking for a textfield that is a single line initially and it auto expands as the text is entered into it and then at some point begins scrolling itself.
This can be achieved partially by using the maxLines: null attribute. But then when a lot of text is entered the Text in the textfield itself overflows.
And if the maxLines is set to a value then the whole textfield itself gets expanded to those many lines to start off with rather than beginning with a single line.
Is there a way to limit the height of textfield at some point like done in many chat apps like WhatsApp and telegram.
Container(
child: new ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 300.0,
),
child: TextField(
maxLines: null,
),
),
),
),
)
In older Flutter versions it was
Container(
child: new ConstrainedBox(
constraints: BoxConstraints(
maxHeight: 300.0,
),
child: new Scrollbar(
child: new SingleChildScrollView(
scrollDirection: Axis.vertical,
reverse: true,
child: new TextField(
maxLines: null,
),
),
),
),
)
Now we actually have minLines parameter of TextField, no workaround needed anymore.
TextField(
minLines: 1,
maxLines: 5,
)
The accepted answer by Gunter is good enough if you don't have any style for the TextField. But if you have at least an underline / bottom border for the TextField, it will disappear when scroll up.
My recommendation is to calculating the lines with TextPainter, then apply the calculated number of lines to TextField. Here's the code, replace your current TextField with LayoutBuilder :
LayoutBuilder(
builder: (context, size){
TextSpan text = new TextSpan(
text: yourTextController.text,
style: yourTextStyle,
);
TextPainter tp = new TextPainter(
text: text,
textDirection: TextDirection.ltr,
textAlign: TextAlign.left,
);
tp.layout(maxWidth: size.maxWidth);
int lines = (tp.size.height / tp.preferredLineHeight).ceil();
int maxLines = 10;
return TextField(
controller: yourTextController,
maxLines: lines < maxLines ? null : maxLines,
style: yourTextStyle,
);
}
)
TextField(
minLines: 1,
maxLines: 5,
maxLengthEnforced: true,
),

How do I make a EditableText or TextField in flutter multiline and wrapping?

I want a way to make a TextField or EditableText's text wrap onto another line.
And how to make them multiline.
I don't know if it matters, but the EditableText sits inside a ListTile > Card > Container.
This is my code:
return ListTile(
title: Card(
child: Container(
padding: EdgeInsets.all(10.0),
child: EditableText(
textAlign: TextAlign.start,
focusNode: _focusNode,
controller: _textEditingController,
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
keyboardType: TextInputType.multiline,
cursorColor: Colors.blue,
),
),
),
);
It doesn't work please help. I have searched everywhere now!
I'm running flutter version: 0.4.4 and dart version: 2.0.0-dev.54.0
You need to set the property maxLines to either null (for infinite growth) or a fixed number.
By default maxLines is equal to 1.

Resources