Align text baseline with text inside a column, using Flutter - flutter

I'm having trouble aligning widgets. I have seen questions on here asking about similar things, however, none of them seem to work for my specific task. I'm trying to create a widget containing an icon and two text widgets. The icon is supposed to be centered over the first text widget, and the other text widget is supposed to be aligned with the baseline of the first.
The way I have gone about doing this is to place the icon and the first text widget in a column, and then place that column in a row together with the second text widget. I'm using crossAxisAlignment: CrossAxisAlignment.baseline and textBaseline: TextBaseline.ideographic in the row widget but for some reason the second text aligns with the icon. It looks like this:
If I instead use crossAxisAlignment: CrossAxisAlignment.end the text widgets do not align properly:
I have tried to put the text widgets in a row and place them in a column together with the icon, but then the icon is no longer centered over the first text widget:
Here's the code used for the first image, the other images are just rearrangements of the same code.
return Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.ideographic,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
widget.icon,
color: color_text_highlight,
size: 20,
),
Text(
widget.data,
style: TextStyle(
fontSize: 28,
fontFamily: 'Quicksand',
color: color_text_highlight,
),
),
],
),
SizedBox(width: 5),
Text(
widget.label,
style: TextStyle(
fontSize: 12,
fontFamily: 'Roboto',
color: color_text_dark,
)
),
],
);
Any help is appreciated!

Column defines its own baseline as a baseline of its first child*. That's why the label at right gets aligned to the bottom of icon:
A simple fix is to make "17:59" the first child of the Column (the icon will go below now) and then use VerticalDirection.up to swap them back:
Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Column(
mainAxisSize: MainAxisSize.min,
verticalDirection: VerticalDirection.up, // <-- reverse direction
children: [
Text('17:59', style: TextStyle(fontSize: 32)), // <-- first child
Icon(Icons.timer),
],
),
Text('mm:ss'),
],
)
* actually, of first child that has a baseline itself, anyway Icon does have it

There may be a solution like this, but the solution may cause problems because it depends on the font size. You will need to change the padding value accordingly.
Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Column(
children: [
Icon(
Icons.timer,
color: Colors.lightGreen,
size: 20,
),
Text(
"17:59",
style: TextStyle(
fontSize: 28,
fontFamily: 'Quicksand',
color: Colors.lightGreen,
),
),
],
),
SizedBox(width: 5),
Padding(
padding: EdgeInsets.only(bottom: 4),
child: Text("mm:ss",
style: TextStyle(
fontSize: 12,
fontFamily: 'Roboto',
color: Colors.white70,
)),
),
],
),
],
)
Google Nexus 9 Tablet
Google Pixel 3a XL
Google Pixel 2

Row allows for a crossAxisAlignment of baseline, set the text baseline too or it will throw an error
Row(
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,

Related

Flutter: How to make upper/bottom index to Text()

Does anybody knows how to make (in a easy way) upper index in text field?
My code:
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic,
children: [
Text(
widget.weather.temp.round().toString(),
style: TextStyle(
color: Colors.white,
fontSize: 150,
),
Text(
'°C',
style: TextStyle(
fontSize: 50.0,
),
)
],
),
This code gives me bottom aligmnet (index)
and how to make upper index like this:
Try this text
Text("${widget.weather.temp.round().toString()}\u00b0\u1d9c")

flutter title automatically go to next line

the code below is in wrapped in a row. i need help in getting the text to automatically go to the next line when there's not enough space. ive been trying to wrap in expanded and stuff but it is not working and throwing me the wrong use of parent widget error. tia
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
Helpers.getChannelName(channel, context.currentUser!),
overflow: TextOverflow.visible,
style: GoogleFonts.lato(
fontSize: 21,
),
maxLines: null,
),
const SizedBox(height: 2),
],
)),
AppBar has limited height, you can have some(2/3) lines like
Text(
Helpers.getChannelName(channel, context.currentUser!),
style: GoogleFonts.lato(
fontSize: 21,
),
maxLines: 3,
softWrap: true,
),
Also, you can try changing text size by wrapping Text widget with FittedBox or using auto_size_text

Flutter. Row with MainAxisAlignment.spaceBetween overflowed

I am new in flutter and I'm trying to implement screen like this:
As you can see I need to make something like a table. I ran into a problem while implementing table rows. Here is my code:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text("2.", ),
const SizedBox(width: 10),
Text(text: "This is second with very long text"),
],
),
),
const SizedBox(width: 8),
Text("500"),
],
),
But I'm getting the error:
A RenderFlex overflowed by 42 pixels on the right.
For some reason my text ("This is second with very long text") doesn't move to a new line, but goes off screen.
Please tell me what am I doing wrong?
You have to wrap your Text("This is second with very long text") widget inside Flexible widget like this:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text("2."),
const SizedBox(width: 10),
Flexible(
child: Text("This is second with very long text"),
),
],
),
),
const SizedBox(width: 8),
Text("500"),
],
),
Just use a ListTile for that.
ListTile(
leading: Text("2. "),
title: Text("This is second with very long text"),
trailing: Text("500"),
)
This is much simpler to implement and handles long text automatically.
You can set padding etc as you wish. You can find more information about list tiles in the official documentation.
you need a Column, to wrap the widgets inside, inside the column you need a first Row that will hold the first and second,
then a HorizontalLine, and then the rest of the rows:
Please, see the example below
Container(
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
//first row:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('First', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
Text('Second', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
]
),
//This SizedBox gives space between widgets
SizedBox(height:5),
Container(color: Colors.black, height: 2, width: double.infinity),
//This SizedBox gives space between widgets
SizedBox(height:5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('1', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
//In order to make the Text multi-lined you need to wrap-it into a SizedBox widget
SizeddBox(
//as I can see, the middle text widget is almost the 70% of the total width
//You can get the total width from MediaQuery.of(context).size.width
width: MediaQuery.of(context).size.width * 0.7,
child: Text('This is first', style: TextStyle(color: Colors.black)),
),
Text('500', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
]
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('2', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
//In order to make the Text multi-lined you need to wrap-it into a SizedBox widget
SizeddBox(
//as I can see, the middle text widget is almost the 70% of the total width
//You can get the total width from MediaQuery.of(context).size.width
width: MediaQuery.of(context).size.width * 0.7,
child: Text('This is second with a very long text', style: TextStyle(color: Colors.black)),
),
Text('12', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
]
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('3', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
//In order to make the Text multi-lined you need to wrap-it into a SizedBox widget
SizeddBox(
//as I can see, the middle text widget is almost the 70% of the total width
//You can get the total width from MediaQuery.of(context).size.width
width: MediaQuery.of(context).size.width * 0.7,
child: Text('This is third with a long text too', style: TextStyle(color: Colors.black)),
),
Text('150', style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)),
]
),
]
)
In this code, you can change the styling and etc as you wish.
I would suggest you to extract the the Row widget that holds the number, the text and the score in a Stateless widget, or in a method that returns Widget object, but it's very soon for this.
I hope I helped you.
Enjoy Flutter!

How to justify text in a flutter column widget?

I would like to align left elements vertically and same with right one with padding, here is what I got as a result, the elements are not aligned and I cannot insert padding in the second row so that left elements are aligned
return InkWell(
child: Column(
children: <Widget>[
Row(
children:<Widget> [
Padding(padding:EdgeInsets.fromLTRB(18.0, 0.0, 0.0, 0.0)),
Text(
product.libelle,
style: theme.textTheme.title,
maxLines: 1,
textAlign: TextAlign.left,
),]),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:<Widget> [
Text(
product.description,
style: theme.textTheme.subtitle,
maxLines: 1,
),
RaisedButton( onPressed: () {},
child: new Text("S\'abonner"),
)
]),
),
);
Use Text Widget and TextAlign.justify :)
Text('my String', textAlign: TextAlign.justify),
Text( 'Vinay',
**textAlign: TextAlign.justify,**
style:TextStyle() ),
incase of Rich Text
RichText(
**textAlign: TextAlign.justify,**
text: TextSpan( style: TextStyle(color: Colors.black, fontSize: 36),
children: <TextSpan>[
TextSpan(text: 'Woolha ', style: TextStyle(color: Colors.blue)),
TextSpan(text: 'dot '),
TextSpan(text: 'com', style: TextStyle(decoration: TextDecoration.underline))]))
Would you try to wrap second row with Padding widget?
Padding(
padding: EdgetInsets.symmetric(horizontal: 18.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children:<Widget> [
Text(
product.description,
style: theme.textTheme.subtitle,
maxLines: 1,
),
RaisedButton( onPressed: () {},
child: new Text("S\'abonner"),
)
]),
)
Your top level widget should be a Row, since you want to horizontally position your widgets next to each others. So what you should do instead is use the following structure (pseudocode):
Row
Column
Text (title)
Text (subtitle)
Button
It's also important to use the correct alignment properties (MainAxisAlignment.spaceBetween on Row so that there is a space between the two main elements and CrossAxisAlignment.start + MainAxisAlignment.center on Column to center things).
I created a pen to demonstrate it: https://codepen.io/rbluethl/pen/QWyNQjE
Hope that helps!
Please try this
Just add below 2 line of code inside you Column Widget.
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,

Overflow problem inside of row. Fittedbox not worked

I have a Row inside that 4 other Rows and inside of the rows one icon and text.
but when the text increases. I got the overflow problem.
I tried FittedBox and Flexible with fit property equal to FlexFit.loose not worked.
this is my code
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.star, color: Color(0xFFf0b649)),
Text(
"4.2",
style: TextStyle(fontSize: 20),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.remove_red_eye),
Text(
"145",
style: TextStyle(fontSize: 20),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.people),
Text(
"14766768675",
style: TextStyle(fontSize: 20),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.favorite_border),
Text(
"دنبال کردن",
style: TextStyle(fontSize: 15),
)
],
),
]),
I had the same problem.
Try wrapping the text widget with a column.
If that doesn't work check this discussion enter link description here.
I am quite sure that you find your answer there if the column wrap doesn't help. GL :)
try Wrap() widget
A Wrap lays out each child and attempts to place the child adjacent to the previous child in the main axis, given by direction, leaving spacing space in between. If there is not enough space to fit the child, Wrap creates a new run adjacent to the existing children in the cross axis.