I have two Text widgets inside a Row. I want to show the text widgets one after another, and wrap the second one to the next line if it doesn't fit in the first line.
I've tried Flexible, Wrap, and what not. I can't seem to get it working.
Row(
children: <Widget>[
Text('This is some text.'),
Text('Another piece of text.')
]
);
I want the output to look something like this (the screen edges are indicated by |):
|This is some text. Another |
|piece of text. |
The best I could get was the following:
|This is some Another piece|
|text. of text. |
Edit: Thanks for replies, everyone. I've tried RichText too, and it works, but I want to bind more than one gesture to each TextSpan element, which cannot be done easily with RichText. I'm about to create a question on that, but stackoverflow doesn't allow me to create more than one question in 90 minutes.
UPDATED ANSWER
The first thing you are doing wrong is using Row to put one text widget under another text.
|This is some text. Another |
|piece of text. |
This is the desired UI are you are trying to achieve right? So From your question, it is clear that you want two text widget one under another.
so this code will work for you. replace Row with Column widget like this. If you want to continue with Row each of your text will wrap but not one text after another. here is the working code. I have putted two text to show you that how they wrap one after another. Checkout the image below to see the result
body: Center(
child: Container(
color: Colors.amberAccent,
width: 200,
height: 200,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Flexible(
fit: FlexFit.tight,
child: Text(
'This is some text.long text more long Text, even more long text',
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
),
Flexible(
fit: FlexFit.tight,
child: Text(
'Another piece of text.not so long text yet needs to be a liitle long text',
style: TextStyle(color: Colors.white, fontSize: 20.0),
),
)
],
),
),
),
),
here is the screenshot
The Wrap Widget will either keep the two Texts on the same line or put the second Text on the next line if there's overflow.
Wrap(
children: [
Text(
'This is some text.',
),
Text(
'Another piece of text.',
),
],
),
You can achieve that using the RichText widget:
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(),
body: RichText(
text: TextSpan(
children: [
TextSpan(text: "This is some text."),
TextSpan(text: "Another piece of text. Another piece of text. Another piece of text. Another piece of text."),
],
),
),
);
}
The RichText widget displays text that uses multiple different styles.
The text to display is described using a tree of TextSpan objects,
each of which has an associated style that is used for that subtree.
The text might break across multiple lines or might all be displayed
on the same line depending on the layout constraints.
RichText
Related
I'm using Wrap widget to solve my overflow problems:
Wrap(
children: [
Text(subtitle, style: TextStyle(color: Color(COLOR_PRIMARY),fontSize: 12.5)),
Image(
image: AssetImage(
drinkNameToImage[widget.post.cocktail] as String),
width: 20,
height: 20,
)
],
),
And when my row of text doesn't overflow everything works fine and looks like this
But when the line overflows it looks like this:
I'd like to have the image next to the text United States, how can I fix?
On your Wrap widget, it is having two Text and Image widgets and based on wrap nature it is working fine. Because while Text widget is taking full width, it will eventually go to next line.
Text widget is taking 1st two lines because it is not having enough spaces and after United States text, rest space is cover by Text widget. You can check it by widget-inspector, or simply wrap with a Container widget and provide color.
In your case you need to use RichText instead of Wrap.
RichText(
text: TextSpan(
children: [
TextSpan(
text: subtitle,
style: TextStyle(
//color: Color(COLOR_PRIMARY),
fontSize: 12.5),
),
WidgetSpan(
child: Image(
image: AssetImage(
drinkNameToImage[widget.post.cocktail] as String,
),
width: 20,
height: 20,
))
],
),
),
Check To learn more about RichText
I am trying to align these text widgets vertically so that they are perfectly centered between the two lines. However, flutter sees the size of the text widget to be as big as the red rectangle behind the text (Background color of text only for illustration purposes) because of the decender line. However, this results in the text looking a bit offcentered. Is there a way to align the text using the baseline and not the decender?
Play with the text height (line-height)
Text('Hey There',
style: TextStyle(height: 5, fontSize: 10),
)
You can try Align widget just wrap your text with Align and provide your alignment
Wrap it in a center widget
Center(
child: Text(
"PAYMENT",
style: TextStyle(
backgroundColor: Colors.blue,
fontSize: 20,
),
textAlign: TextAlign.center,
),
)
Dartpad:
https://dartpad.dev/flutter?null_safety=true&id=3b0bf085892c1867012f5dd00713ccf7
I think what your looking for is to use the "CrossAxisAlignment" attribute in the Column widget.
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Delivery'),
Text('Payment'),
Text('Total'),
],
)
I am trying to get some text left aligned and fitting to a single row, with the last part being kept in it's original form. Something like the following:
// Original
A really long name which would wrap / Yesterday
// Output
A really long name... / Yesterday
The code below works for the above example, but:
// Original
Short Name / Yesterday
// Required Output (all left aligned)
Short Name / Yesterday
// Actual Output
Short Name / Yesterday
Is there a way to achieve that? The code below is correctly shortening the left-hand component but alignment is off.
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blue,
child: Text('AB'),
),
title: Text('Some text',
overflow: TextOverflow.ellipsis, maxLines: 1),
subtitle: Row(children: <Widget>[
Container(
child: Text('Person Name,
overflow: TextOverflow.ellipsis, maxLines: 1)),
Expanded(
flex: 1,
child:
Text(' / Yesterday'))
]),
),
]);
I met the same problem and finally I found a solution.
Put your "A really long name which would wrap" text into Flexible() instead of Expanded().
This will make your text get free spaces only when needed. So when your text content is not long enough, it won't take all spaces.
Just add the mainAxisAlignment property and set it to mainAxisAlignment.spaceBetween. This will space out your container and Text. Just remove the flex property from the expanded widget. It already defaults to 1.
I want to implement a Row having two Text widgets and a middle line like this:
The following code is my current implementation.
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'Text',
overflow: TextOverflow.ellipsis
),
Expanded(
child: Container(
padding: EdgeInsets.only(left: 16, right: 16),
height: 1,
child: Container(
color: Colors.black
)
),
),
Text(
'Right Text'
)
]
)
The problem of this code is that the left text overflows if it is long like this:
The expected output is:
Wrapping the first Text widget with a Flexible can solve the overflow issue, but the output is not the same as the expected output because of the Expanded widget that fills the space between two Text widgets with a line.
How can I achieve this? Any help is highly appreciated!
I am using Flutter programming. I need to display a title and a button next to the title. If the text length is less button also should display next to the text. If text length is more i want to fix the text length as maximum 200px and need to show the button next to the title.
I am using the below code. And working fine with the less text length.
Problem is: If text length is more, then my button is moving out of screen. You can see the behaviour in the below attached image.
Row(
children: <Widget>[
Container(
child: RichText(
overflow: TextOverflow.ellipsis,
strutStyle: StrutStyle(fontSize: 12.0),
text: TextSpan(
style: TextStyle(color: Colors.white), text: model.title),
),
),
Text("My Button"),
],
)
You can put maximum characters
text.substring(0,150)
I think there's no maxLength property for RichText and Text widget. If you are using RichText class, you'll have maxLines property that can be used. I tried to recreated your case and wrapped RichText widget with Flexible widget that lets the child widget to use only the minimum available space. But I wasn't able to replicate the error you mentioned. The long text I used gets ellipsis and the button doesn't go out of the screen. Note that I also used maxLines property which if you set to 2, will wrap the long text in new line without moving away the button and the long text will be shown as ellipsis. Sample working code below:
body: Center(
child: Row(
children: <Widget>[
Container(
child: Flexible(
child: RichText(
maxLines: 2,
overflow: TextOverflow.ellipsis,
strutStyle: StrutStyle(fontSize: 12.0),
text: TextSpan(
style: TextStyle(color: Colors.white), text: 'I am using Flutter programming. I need to display a title and a button next to the title. If the text length is less button also should display next to the text. If text length is more i want to fix the text length as maximum 200px and need to show the button next to the title.'),
),
)
),
Text("My Button"),
],
)
)
If you set maxLines to 1, the long text will wrap in ellipsis.
Hope this helps.
String addressText = userAddress.address.toString();
if(addressText.length > 22)
addressText = addressText.substring(0,22);
You can check length and split string if exceeds max length.
you can use Expanded or give fixed width to container of rich text, like this with Expanded widget:-
Row(
children: <Widget>[
Expanded(
child: RichText(
overflow: TextOverflow.ellipsis,
strutStyle: StrutStyle(fontSize: 12.0),
text: TextSpan(
style: TextStyle(color: Colors.white), text: model.title),
),
),
Text("My Button"),
],
)