Related
import 'package:flutter/material.dart';
class CardNote extends StatelessWidget {
const CardNote({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Card(
elevation: 3,
color: Colors.amber,
child: SizedBox(
width: 200,
height: 200,
child: Center(
child: Text(
'Card 1',
)),
),
),
Card(
elevation: 3,
color: Colors.amber,
child: SizedBox(
width: 200,
height: 200,
child: Center(
child: Text(
'Card 2',
)),
),
),
],
),
),
),
);
}
}
When I add this widget to the page where I want to show the cards, I can show 2 widgets in a single line. Then when I call the same widget again, I get the following error.
RenderCustomMultiChildLayoutBox object was given an infinite size during layout.This probably means that it is a render object that tries to be as big as possible, but it was put inside another render object that allows its children to pick their own size.
return Scaffold(
body: Container(
child: Row(
children: const [
CardNote(),
SizedBox(
height: 50,
),
CardNote()
],
),
),
);
This is how I add the cards to the page I want to show.
This is how I want to show 4 cards in the middle of the page
This is how it looks on my page. It shows at the top of the page, not in the middle.
You can wrap your CardNote widget with Expanded widget. And use a top level scrollable widget. Also you dont need to us multiple scaffold
home: Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: const [
CardNote(),
SizedBox(
height: 50,
),
CardNote(),
],
),
),
),
While the card is fixed width, you can provide it
class CardNote extends StatelessWidget {
const CardNote({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
Card(
elevation: 3,
color: Colors.amber,
child: SizedBox(
width: 200,
height: 200,
child: Center(
child: Text(
'Card 1',
)),
),
),
Card(
elevation: 3,
color: Colors.amber,
child: SizedBox(
width: 200,
height: 200,
child: Center(
child: Text(
'Card 2',
)),
),
),
],
),
),
);
}
}
You are trying to add a row which has alignment of spaceEven inside another row. When you added the first set of cards it got aligned evenly. On second set you have 2 set of rows inside a row each one has alignment of spaceEven..
Depending on the layout if you wish to show these cards one below the other set then use a Column widget
return Scaffold(
body: Container(
child: Column(//here
children: const [
CardNote(),
SizedBox(
height: 50,
),
CardNote()
],
),
),
);
I am making layout for flutter application
What I want to do is
-----------------------
|[i] [text] |
| |
Icon should be the left (padding 5px)
And text should be the center of screen.
At first I should use the Column
However my layout is not the same proportion
It might be simple though , how can I make it??
Stack() is one of the many options that you can use. Something like this:
Stack(
children:<Widget>[
Padding(
padding: EdgeInsets.only(left: 5),
child: Icon(Icons.info),
),
Align(
alignment: Alignment.topCenter,
child: Text("I'm on the top and centered."),
),
],
),
One way you can do this is something like this..
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: EdgeInsets.all(5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.info),
Text('text'),
Opacity(opacity: 0, child: Icon(Icons.info)),
],
),
),
Padding(
padding: EdgeInsets.all(5),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.info),
Text('second text'),
Opacity(opacity: 0, child: Icon(Icons.info)),
],
),
),
],
);
}
Result:
I might be late, but I want this answer to be there, if some one would find it better for the development purposes in future time.
We can make a reusable widget, which we can use it inside the main widget. The widget will accept text, and icon to be passed when called
// IconData is the data type for the icons
Widget myWidget(String text, IconData icon) => Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: [
// this will be used a left-padding param
SizedBox(width: 20.0),
// using it here
Icon(icon, size: 28.0, color: Colors.greenAccent),
SizedBox(width: 5.0),
// this will take the remaining space, and then center the child
Expanded(child: Center(child: Text(text)))
]
);
To use in the main Widget, just do like this:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// calling our widget here
myWidget('FirstText', Icons.alarm),
SizedBox(height: 20.0), // this is used as a top margin
myWidget('SecondText', Icons.notifications)
]
)
If you wanna check out the sources which I used, please see:
Expanded class
SizedBox class
The result you will get is this:
This was an answer I gave a while ago for this same issue, but the other situation was vertical (a Column) instead of horizontal (a Row). Just swap the Row and Columns out for a Column and Rows in this example and you'll get the idea.
My code has grey added in order to show the difference between the two approaches.
A Stack will work, but it's overkill for this, this kind of problem is part of why we have Expandeds and Flexibles. The trick is to use three Flexibles (2 Expandeds and a Spacer). Put the Spacer on top. It and the bottom Expanded must have the same flex value in order to center the middle Expanded.
import 'package:flutter/material.dart';
class CenteringOneItemWithAnotherItemInTheColumn extends StatelessWidget {
const CenteringOneItemWithAnotherItemInTheColumn({
Key key,
}) : super(
key: key,
);
/// Adjust these values as needed
final int sameFlexValueTopAndBottom = 40; // 40%
final int middleFlexValue = 20; // 20%
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Column Alignment Question'),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Spacer(),
const Text(
'Cent',
style: TextStyle(
fontSize: 64,
),
),
const Spacer(),
const Text(
'Bot',
style: TextStyle(
fontSize: 64,
),
),
],
),
Column(
children: <Widget>[
/// The key is to have the Spacer and the bottom Expanded
/// use the same value for flex. That will cause the middle
/// child of the Column to be centered vertically.
Expanded(
flex: sameFlexValueTopAndBottom,
child: Container(
width: 100,
color: Colors.grey[300],
),
),
Expanded(
flex: middleFlexValue,
child: const Align(
alignment: Alignment.center,
child: Text(
'Cent',
style: TextStyle(
fontSize: 64,
),
),
),
),
Expanded(
flex: sameFlexValueTopAndBottom,
child: Container(
color: Colors.grey[300],
child: const Align(
alignment: Alignment.bottomCenter,
child: Text(
'Bot',
style: TextStyle(
fontSize: 64,
),
),
),
),
),
],
),
],
),
);
}
}
I have to position 2 children widgets inside a Column parent widget. I want one of them to be positioned in the center and the other at the end of the column. What is the best way to do that?
import 'package:flutter/material.dart';
class Screen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Screen'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center, // this is wrong, it positions both the widgets in the center
children: <Widget>[
Text('This text should be at the center of the column'),
Text('This text should be at the end of the column'),
],
),
);
}
}
you can use the Spacer widget like this:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Spacer(),
Text('This text should be at the center of the column'),
Spacer(),
Text('This text should be at the end of the column'),
],
),
);
(EDIT: I changed the code and added grey to mine in order to show a comparison, so you can see what I mean when I say it will be offset by half. You have to increase the font size to see the difference.)
It's not quite as easy as the other answers because the first text has to be centered and if you only use two elements in your Column then no matter what you do it's either going to make the top item be off-center by half the height of the bottom text (as in using only two Expandeds) or the design will be rigid and therefore may not display correctly on different sized devices.
So, the trick is to use three Flexibles (2 Expandeds and a Spacer). Put the Spacer on top. It and the bottom Expanded must have the same flex value in order to center the middle Expanded.
Only then will using "alignment: Alignment.center" give the needed result for the top text.
import 'package:flutter/material.dart';
class CenteringOneItemWithAnotherItemInTheColumn extends StatelessWidget {
const CenteringOneItemWithAnotherItemInTheColumn({
Key key,
}) : super(
key: key,
);
/// Adjust these values as needed
final int sameFlexValueTopAndBottom = 40; // 40%
final int middleFlexValue = 20; // 20%
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Column Alignment Question'),
),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Spacer(),
const Text(
'Cent',
style: TextStyle(
fontSize: 64,
),
),
const Spacer(),
const Text(
'Bot',
style: TextStyle(
fontSize: 64,
),
),
],
),
Column(
children: <Widget>[
/// The key is to have the Spacer and the bottom Expanded
/// use the same value for flex. That will cause the middle
/// child of the Column to be centered vertically.
Expanded(
flex: sameFlexValueTopAndBottom,
child: Container(
width: 100,
color: Colors.grey[300],
),
),
Expanded(
flex: middleFlexValue,
child: const Align(
alignment: Alignment.center,
child: Text(
'Cent',
style: TextStyle(
fontSize: 64,
),
),
),
),
Expanded(
flex: sameFlexValueTopAndBottom,
child: Container(
color: Colors.grey[300],
child: const Align(
alignment: Alignment.bottomCenter,
child: Text(
'Bot',
style: TextStyle(
fontSize: 64,
),
),
),
),
),
],
),
],
),
);
}
}
Another way is to use an empty SizedBox at the start and the mainAxisAlignment: MainAxisAlignment.spaceBetween,
class Screen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Screen'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
height: 0.0,
width: 0.0,
),
Text('This text should be at the center of the column'),
Text('This text should be at the end of the column'),
],
),
);
}
}
One of the way could be using Expanded widget along with alignment as for the need
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Screen'),
),
body: Column(
// mainAxisAlignment: MainAxisAlignment.center, // this is wrong, it positions both the widgets in the center
children: <Widget>[
Expanded(child: Container(alignment:Alignment.bottomLeft,child: Text('This text should be at the center of the column'))),
Expanded(child: Container(alignment: Alignment.bottomLeft, child: Text('This text should be at the end of the column'))),
],
),
);
}
I'm re-writing a simple app which calculates averages. However, I have a hard time with a TextField. I would like it to be exactly as on a first screenshot.
The TextField's width is stretched, I don't want that. I want it to be exactly as it is on the screenshot.
Desired look:
What I have:
Code:
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
class ArithmeticAverageScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('arithmetic_average_title').tr(),
),
body: Container(
padding: EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
Card(
child: Container(
padding: EdgeInsets.symmetric(vertical: 20.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.help),
title: Text('arithmetic_average_help').tr(),
subtitle: Text('arithmetic_average_help_content').tr(),
)
],
),
)
),
SizedBox(height: 16.0),
Card(
child: Container(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('arithmetic_average_your_grades', style: Theme.of(context).textTheme.headline5).tr(),
SizedBox(height: 16.0),
Text('arithmetic_average_grades_one_at_a_time', style: Theme.of(context).textTheme.headline6,).tr(),
SizedBox(height: 16.0),
Text('arithmetic_average_grade', style: Theme.of(context).textTheme.subtitle2).tr(),
TextField()
],
),
),
)
],
),
)
);
}
}
This will help you make generic width on all devices, so here width * 0.3 means it will take 30% of the screen width
Container(
width: MediaQuery.of(context).size.width * 0.3,
child: TextField(),
)
Use Row Widget, and put Expanded Widget as child Widget and inside that put your widgets, as Expanded will take up equal space.
return Row(
children: [
Expanded(
child: TextField();
),
Expanded(
child: Button();
)
],
);
When ever you want to play with height and width you can use the widget Container.If you want to play with a property which cannot found in the widget you are using wrap it with a widget with that property will help you.
Container(
margin: const EdgeInsets.only(right: 150),
child: new TextField(
decoration: new InputDecoration(
hintText: 'Grade',
)
)
)
You can try to wrap your TextField and Button with two Flexible widgets and apply desired proportions, e.g. 1:2 which would give you following result:
Row(
children: [
Flexible(
flex: 1,
child: TextField(),
),
Flexible(
flex: 2,
child: RaisedButton(
child: Text('Hello'), onPressed: () {}),
)
],
)
],
You can also replace the first Flexible with SizedBox and set an exact value, e.g:
Row(
children: [
SizedBox(
width: 100.0,
child: TextField(),
),
Flexible(
flex: 2,
child: RaisedButton(
child: Text('Hello'), onPressed: () {}),
)
],
)
],
TextField doesn't have an intrinsic size (width) constraint so it will always try to occupy all horizontal space. Flexible allows to constraint it to desired width in a Row.
Full example on DartPad.
Can I position a widget based on another widget?
like this:
Tiled Layout
Without
flutter_staggered_grid_view Library
There is no Widget similar to ConstraintLayout but you can achieve what you want using different widgets, like this example:
class Testing2 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
child: Row(
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Flexible(
flex: 1,
child: Container(
color: Colors.deepOrange,
),
),
Flexible(
flex: 2,
child: Container(
color: Colors.lightBlue,
),
),
],
),
),
Flexible(
child: Column(
children: <Widget>[
Flexible(
flex: 3,
child: Container(
color: Colors.orange,
)),
Flexible(
flex: 1,
child: Row(
children: <Widget>[
Flexible(
flex: 2,
child: Container(
color: Colors.blue,
)),
Flexible(child: Container(color: Colors.green))
],
),
)
],
),
)
],
),
);
}
Also you can take a look this link to know about Layout Widgets: https://flutter.io/widgets/layout/
You can try this:
https://github.com/hackware1993/Flutter-ConstraintLayout
Build flexible layouts with constraints, Similar to Android ConstraintLayout.
No matter how complex the layout is and how deep the dependencies are, each child element of ConstraintLayout will only be measured once, This results in extremely high layout performance.