Flutter. Row with MainAxisAlignment.spaceBetween overflowed - flutter

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!

Related

I want to align the starting place of two texts

I have one "row" and two "text" widgets inside. I want to align the starting place of two texts. ie "m. name" and "m105" should line up.
Container(
child: Row(
children: [
Container(
child: Align(
alignment: Alignment.topLeft,
child: Text(
"M. Adı: ",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
// SizedBox(
// width: 20,
// ),
Expanded(
child: Text(
"$productName",
overflow: TextOverflow.ellipsis,
maxLines: 3,
softWrap: true,
),
),
],
),
),
Try
Row() widget attribute
crossAxisAlignment: CrossAxisAlignment.start
Text() widget attribute
textAlign: TextAlign.start,
/// Try something like that
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"M. Adı: ",
style: TextStyle(fontWeight: FontWeight.bold),
),
),
SizedBox(width: 5),
Flexible(
child: Text(
"$productName",
textAlign: TextAlign.start,
),
),
],
),
Add crossAxisAlignment: CrossAxisAlignment.center, to your Row widget it should be aligned as you desired or still if it doesnt works just try changing center with other values check which one works for you...
and even after adding above property to your Row widget then you would have to remove alignment of topleft in your text of m.name

How to use expanded in rich text flutter

Hi good evening everyone. I am trying to use expanded in my rich text but unable to achieve. My main problem is that widget get overflow on different screen size so I need a way of how to achieve expanded since expanded will help text to fit according to sizer of the screen
code :
Container(
width: double.maxFinite,
height: 100,
margin: const EdgeInsets.only(left: 150,top: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Watch your playlist",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: color.AppColor.homePageDetails
),
),
SizedBox(height: 10,),//56:39
RichText(
text: TextSpan(
text: "stream up\n",
style:TextStyle(
color: color.AppColor.homePagePlanColor,
fontSize: 16
),
children: [
TextSpan(
text:"check out your favourite"
)
]
),
),
],
),
)
I have had the same problem a long time ago, one solution for this, is to use Flexible Widget inside a Row:
Row(
children: [
Flexible(
child: RichText(
text: const TextSpan(
text: "stream up\n",
color: color.AppColor.homePagePlanColor,
style: TextStyle(fontSize: 16),
children: [
TextSpan(text: "check out your favourite")
]),
),
),
],
),
Make sure to use const to avoid performance issues as well.
you can use this package = flutter_screenutil
it proportions all the application content for different screen sizes
The overflow issue is coming from Container's height. You can simply remove height from Container , It will work fine without any issue
Container(
width: double.maxFinite,
margin: const EdgeInsets.only(left: 150, top: 50),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Note: left padding 150 taking 150px on left, and "stream up\n" => \n creating newline. default it will take as much size at it is needed
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: RichText(
text: TextSpan(
worked for me

Center certain elements vertically in a Row widget

I have the following Widget tree of a ListView item:
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Align(
child: Assets.images.select.image(height: 20, width: 20),
),
),
Expanded(
flex: 4,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(right: 16),
child: Text(
food.name,
style: GoogleFonts.cabin(
color: Theme.of(context).primaryColor,
fontSize: FontSize.medium.size,
fontWeight: FontWeight.w700),
),
),
Container(
margin: EdgeInsets.only(top: 4),
child: Text(
"100 g",
style: GoogleFonts.cabin(
color: Color(0xFF777777),
fontSize: FontSize.small.size,
fontWeight: FontWeight.w500),
),
),
],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Align(
alignment: Alignment.centerRight,
child: Text(
"${food.carbohydratesPerGram} g / HC",
style: GoogleFonts.cabin(
color: Theme.of(context).primaryColor,
fontSize: FontSize.medium.size,
fontWeight: FontWeight.w400),
),
),
],
),
)
],
)
But it turns out like this:
I tried putting the ball in a column with "mainAxisAlignment" set to "mainAxisAlignment.center"
How can I get the ball on the left vertically centered in the row?
You can use crossAxisAlignment.
When you are in a row element the main is horizontal axis and the cross is vertical axis
When you are ina column the main is verticla axis and the cross is horizontal axis.
So in your Row element to center element in vertical axis you need to use
crossAxisAlignment: CrossAxisAlignment.center
Managed to get it somewhat working: instead of using an image widget, I used an IconButton widget and it magically worked
Add alignment: Alignment.center to you Assets.images.
Expanded(
child: Align(
alignment: Alignment.center, // This Here
child: Assets.images.select.image(height: 20, width: 20),
),
),
And I think your row is taking the height of your whole screen. If that is the case your image will come to the center of the screen coz your row is on the whole screen make sure that is not the case.

Flutter how to move an item to the bottom

I have this two items that once needs to appear in the middle but the other other needs to move to the bottom.
import 'package:flutter/material.dart';
class WelcomeScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'K',
style: TextStyle(
fontSize: 200,
color: Colors.white,
decoration: TextDecoration.none,
fontStyle: FontStyle.italic,
),
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [Text('hello')],
)
],
),
);
}
}
This is how it looks.
I want to move the Hello Text to the bottom. How can I do that?
You need to use two things for that, to make it work more efficiently. These are:
Expanded Class -> This will provide space, that is, takes up the remaining space
Align class -> This will help you to align the item
Please Note: Align(), itself, cannot aligns, the item, unless space is given. If you just use the Align(), you will not see any change, cos Text('Hello') looks for space, but no space is there.
Code
Container(
width: double.infinity, // <-- Takes up total width of the device
height: double.infinity, // <-- Takes up the total height of the device
color: Colors.blue,
child: Column(
children: [
Expanded(
flex: 2, // <-- Flex takes care of the remaining space ratio
child: Center(
child: Text(
'K',
style: TextStyle(
fontSize: 200,
color: Colors.white,
decoration: TextDecoration.none,
fontStyle: FontStyle.italic,
),
)
)
),
Align(
alignment: Alignment.bottomCenter,
child: Text('Hello', style: TextStyle(color: Colors.white, fontSize: 17.0))
)
]
)
)
Result
If you don't want your K text to move on top, you would have to use Stack. This way, your widget inside can position themselves anywhere they want.
Stack(
alignment:Alignment.center,
children:[
Text("K"),
Align(
alignment:Alignment.bottomCenter,
child:Text("hello"),
),
]
),
Take a look at the stack widget here: https://www.youtube.com/watch?v=liEGSeD3Zt8
return Container(
color: Colors.blue,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Spacer(),
Text(
'K',
style: TextStyle(
fontSize: 200,
color: Colors.white,
decoration: TextDecoration.none,
fontStyle: FontStyle.italic,
),
),
Spacer(),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [Text('hello')],
)
],
),
);
how about this way? add two Spacer

Align text baseline with text inside a column, using 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,