ListTile: Wrap text in trailing widget - flutter

I was trying to use a ListTile to display a small title on the left, and then a longer text in the trailing widget. My idea es to let the trailing text to split out into multiple lines if there is not enough horizontal space.
I also tried to create my own tile using the following code:
Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 12),
child: Text(
"Campus",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
),
),
),
Text(
"20h course - New students -",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
),
),
],
),
),
Using this code in a Pixel 2 XL emulator, as there is enough space, everything is in the same line as expected:
But when I'm trying it in a Nexus One emulator, because of its size, here is the output:
In order to allow the text to split in multiples lines, I wrapped the text on the right into a flexible widget:
Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 12),
child: Text(
"Campus",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
),
),
),
Flexible(
child: Text(
"20h course - New students -",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
),
),
),
],
),
),
But then the problem is that even though the text is split in two lines, it is using more space than needing, so there is empty space left:
I have also tried to use an align widget to move the text to the end, but no luck either. Any ideas?

Wrap your Text with container and give it alignment left or right. Then the important part is, add textWidthBasis: TextWidthBasis.longestLine, to your Text. Code:
Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 12),
child: Text(
"Campus",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
),
),
),
Flexible(
child: Container(
alignment: Alignment.centerLeft,
child: Text(
"20h course - New students - sd f sdfsddssdfsdfs dfs df sf sdf sdf ",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
),
textWidthBasis: TextWidthBasis.longestLine,
),
),
),
],
),
),

Flexible expands to fill all the available space. So if you want both widgets have the same space you can wrap the with flexible. Also you can use softWrap for you text.
Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
child: Padding(
padding: const EdgeInsets.only(right: 12),
child: Text(
"Campus",
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
),
),
),
),
Flexible(
child: Text(
"20h course - New students -20h course - New students -20h course - New students -20h course - New students -20h course - New students -",
softWrap: true,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
),
),
),
],
),
),
You can also use Expanded instead of `Flexible

Related

Why isn't TextOverflow.Ellipsis working as intended with my Text Widget?

I'm trying to use TextOverflow.Ellipsis to make sure some text data doesn't cause an overflow error. Only problem is that it doesn't seem to be working properly for me. I add the property but the text doesn't get shortened and still causes an overflow error. Anyone got an idea of why this is occurring and how to fix it?
This is how it currently looks. Even with Ellipsis added.
This is the code that renders it all.
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(top: 13, left: 10),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(mileage[index].trippurpose,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.black,
fontFamily: 'Montserrat'),
overflow: TextOverflow.ellipsis,
softWrap: false,
textAlign: TextAlign.center)
],
)),
Padding(
padding: EdgeInsets.only(left: 10),
child: Row(
children: [
Text(
'${mileage[index].tripfrom} - ',
style: TextStyle(
color: Colors.black,
fontStyle: FontStyle.italic),
),
Padding(
padding: EdgeInsets.only(right: 36),
child: Text(
mileage[index].tripto,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.black,
fontStyle: FontStyle.italic
),
),
)
],
),
),
],
),),
First, I would always add the maxLines: 1 property to the Text widget in this kind of layouts.
Then...
If you can, try removing the Row widget.
If you can't remove the Row widget, wrap the Row widget with the Expanded widget around.

Renderflex overflow caused by row

I am trying to implement simple one-two line text.
Text will have a starting text then icon and ending text.Due to different styles i am using row with text,icon and text widgets.
I am getting A RenderFlex overflowed by 16 pixels on the right. error.
i enclose the row in flexible and expanded but still not working. i just want the text to drop at the end of line to next line.
Container(
padding: EdgeInsets.only(
left: 20,
right: 20,
),
width: mdq.size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Tap ',
style: TextStyle(
fontSize: 17,
),
),
Icon(Icons.add),
Text(
'on the right hand corner to start a new chat.',
style: TextStyle(
fontSize: 17,
),
),
],
),
),
Container(
margin: EdgeInsets.symmetric(
vertical: 15,
),
child: Text(
'You can communicate with the user who have installed Just Meetups and Deals app',
style: TextStyle(
color: Colors.grey,
fontSize: 16,
),
),
),
Container(
margin: EdgeInsets.symmetric(
vertical: 15,
),
child: InkWell(
onTap: () {},
child: Text(
'Start communicating',
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
);
Use the Expanded widget
Container(
padding: EdgeInsets.only(
left: 20,
right: 20,
),
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Tap ',
style: TextStyle(
fontSize: 17,
),
),
Icon(Icons.add),
Expanded(
child: Text(
'on the right hand corner to start a new chat.',
style: TextStyle(
fontSize: 17,
),
),
)
],
),
Container(
margin: EdgeInsets.symmetric(
vertical: 15,
),
child: Text(
'You can communicate with the user who have installed Just Meetups and Deals app',
style: TextStyle(
color: Colors.grey,
fontSize: 16,
),
),
),
Container(
margin: EdgeInsets.symmetric(
vertical: 15,
),
child: InkWell(
onTap: () {},
child: Text(
'Start communicating',
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.blue,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
Here's a codepen of it working
You need not use any flex like [Expanded, Flexible, etc] for rows in the column because rows default takes max-width available by column
You are getting an error because your row child width is more than available screen size
you can use Expanded for the children of large width of rows in Expanded to wrap the child in available width inside a row.

How to align text widget in rows in google flutter?

I'm trying to align several a text which is in rows (a number, a small padding, followed by said text) in a column and don't know how to achieve it.
I already tried out every MainAxisAlignment setting in the rows property.
This screenshot should clarify my issue: The left part is the mockup and how it's supposed to look like, right-hand side is the current state in flutter.
I want the text to be aligned at the green line that I added to visualize my problem (so the first text needs to start a bit more to the right).
My code:
Widget singleStep(BuildContext context, int numToPrint, String text,
{String fineprint = ""}) {
return Padding(
padding: EdgeInsets.only(
bottom: 0.023 * getScreenHeight(context),
left: 0.037 * getScreenWidth(context)),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
RichText(
text: TextSpan(children: <TextSpan>[
TextSpan(
text: "#",
style: GoZeroTextStyles.regular(_NUMBERFONTSIZE,
color: GoZeroColors.green)),
TextSpan(
text: numToPrint.toString(),
style: GoZeroTextStyles.regular(_NUMBERFONTSIZE))
])),
Padding(
padding: EdgeInsets.only(left: 0.017 * getScreenWidth(context)),
child: RichText(
text: TextSpan(
style: GoZeroTextStyles.regular(_TEXTSIZE),
children: <TextSpan>[
TextSpan(text: text + "\n"),
TextSpan(
text: fineprint,
style: GoZeroTextStyles.regular(_FINEPRINTSIZE))
])))
],
));
}
All steps are wrapped in a column, which is a child of a Stack.
Advice is gladly appreciated. Also if you got any other advice to improve the code, feel free to leave a comment :)
Thank you in advance!
Cheers,
David
I hope I understand you well. There are some advices for your problem to solve it:
Consider to add SizedBox(width:20.0) before RichText widgets to achieve the align in mockup.
Looks like you want to make all Text widgets centered. Consider to add center widget so they align themselves at the center of column or row.
#override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: Column(children: [
Expanded(
flex: 4,
child: Container(
alignment:Alignment.center,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.grey, width: 1.0)),
child:Text('I\'m in Circle',textAlign: TextAlign.center,
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.bold,
color: Colors.black)))),
SizedBox(height: 15),
Text('Title',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 19,
fontWeight: FontWeight.bold,
color: Colors.black)),
SizedBox(height: 10),
Expanded(
flex: 3,
//Use listview instead of column if there are more items....
child: Column(
mainAxisAlignment:MainAxisAlignment.spaceEvenly,
children: [
Row(children: [
Padding(
padding:
const EdgeInsets.symmetric(vertical: 8, horizontal: 15),
child: Text('#1',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.green)),
),
Text('Your text goes here.......\nSecond line',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.black)),
]),
Row(children: [
Padding(
padding:
const EdgeInsets.symmetric(vertical: 8, horizontal: 15),
child: Text('#2',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.green)),
),
Text('Your text goes here.......\nSecond line',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.black)),
]),
Row(
children: [
Padding(
padding:
const EdgeInsets.symmetric(vertical: 8, horizontal: 15),
child: Text('#3',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.green)),
),
Text('Your text goes here.......\nSecond line',
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
color: Colors.black)),
])
]))
]));
}
My suggestion would be to return Container instead of Padding from the Widget singleStep and use the property padding of the container to set the padding.
Screenshot
Below is a very basic code snippet using Container using which I could add padding to the left of texts:
void main() {
runApp(
MaterialApp(
home: SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
body: Container(
margin: EdgeInsets.only(top: 20.0),
padding: EdgeInsets.only(
left: 20.0,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
"Hello World",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.green,
fontSize: 20.0,
),
),
Text(
"Hello World",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.green,
fontSize: 20.0,
),
),
Text(
"Hello World",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.green,
fontSize: 20.0,
),
),
],
),
),
),
),
),
);
}
Hope this is helpful.

Flutter - multiline label inside row

Layout is defined as follows:
var cardLayout = Flexible(
child: new Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
child: Row(children: <Widget>[
Text(categoryIcon,style: TextStyle(color: Colors.lightBlue, fontFamily: 'Fontawesome', fontWeight: FontWeight.normal)),
Text(" " + categoryName, maxLines: 3, style: TextStyle(color: Colors.lightBlue, fontWeight: FontWeight.normal)) //Overflow!!
]),
padding: EdgeInsets.only(bottom: 10.0,left: 10.0, top: 10.0),
),
Padding(
child: Text(title, maxLines: 3, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.normal, fontSize: 16)),
padding: EdgeInsets.only(bottom: 10.0,left: 10.0, top: 10.0),
),
Padding(
child: new Text(address, style: TextStyle(fontStyle: FontStyle.normal)),
padding: EdgeInsets.only(bottom: 15.0,left: 10.0, top: 10.0),
),
Visibility(
child: Padding(
child: new Text("⬤ " + statusName, style: TextStyle(fontStyle: FontStyle.normal,color:HexColor(statusColor))),
padding: EdgeInsets.only(bottom: 15.0,left: 10.0, top: 10.0),
),
visible: type == ResponseMessageType.MESSAGE_TYPE_EVENT|| type == ResponseMessageType.MESSAGE_TYPE_MY_EVENT,
)
],
),
)
);
I don't understand why category label is not multiline. It overflows (I added comment in pasted code to show wchich label I mean). It seems problem is Row. How to keep Row, but make label multiline?
Simpy Wrap Text widget with - Flexible to make it Multi-line.
Flexible(
child: Text(" " + categoryName,
maxLines: 3,
style: TextStyle(
color: Colors.lightBlue,
fontWeight: FontWeight.normal)),
),

Make Column's child(e.g. Container Layout) wrap_content in horizontal

As the picture shows:
There is a solid line between the two Text(Pokémon, 11.25 AM). What I want is the length of the line equaling to the longest Text length. But the line behaved like match_parent.
In Android Native we can use a vertical LinearLayout, and set android:layout_width="wrap_content" limit in horizontal.
In Flutter we can only set Column mainAxisSize: MainAxisSize.min limit in vertical.
I guess the problem is due to Divider. When Divider is gone, the Column's width is wrap_content.
Experiment is as follows:
Container(
color: Colors.red,
margin: EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(vertical: 8.0),
padding: EdgeInsets.all(4.0),
child: Text(
'Pokémon',
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Divider(
height: 2.0,
color: Colors.white,
),
Container(
margin: EdgeInsets.only(top: 8.0),
child: Text(
'11.25 AM',
style: TextStyle(
color: Colors.white,
fontSize: 12.0,
fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
You can use - IntrinsicWidth widget. Wrap Column with it.
Container(
color: Colors.red,
margin: EdgeInsets.symmetric(horizontal: 8.0),
child: IntrinsicWidth(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(vertical: 8.0),
padding: EdgeInsets.all(4.0),
child: Text(
'Pokémon',
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Divider(
height: 2.0,
color: Colors.white,
),
Container(
margin: EdgeInsets.only(top: 8.0),
child: Text(
'11.25 AM',
style: TextStyle(
color: Colors.white,
fontSize: 12.0,
fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
),