Incorrect use of ParentDataWidget - Row and container - flutter

I am trying to build a container with a row. In this row, I would like to have 4 icons.
If I have done it, my problem is that I am getting an error "Incorrect use of ParentDataWidget".
I do not find where the problem is coming from. If you could help me to solve this it would be appreciated. Many thanks.
Card(
child:
Container(
// color: Colors.red,
alignment: Alignment.center,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children:[
//Time
FlatButton(
child:
InkWell(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.timer),
Text('Time'),
],
)
),
onTap: () {
print("Tapped on Time");
},
),
),
//Energy
FlatButton(
child:
InkWell(
child: Expanded(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.battery_charging_full),
Text('Energy'),
],
)
),
),
onTap: () { },
),
),
//Important
FlatButton(
child:
InkWell(
child: Expanded(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isImportant =="true" ? Icon(Icons.star,color: Colors.orange,) :
Icon(Icons.star_border, color: Colors.grey,),
// Icon(Icons.battery_charging_full),
Text('Important'),
],
)
),
),
onTap: () {
setState(() {
if (isImportant=='true'){
isImportant = 'false';}
else
{isImportant= 'true';
}
});
},
),
),
//Urgent
FlatButton(
child:
InkWell(
child: Expanded(
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isUrgent =="true" ? Icon(Icons.flag,color: Colors.red,) :
Icon(Icons.outlined_flag, color: Colors.grey,),
// Icon(Icons.battery_charging_full),
Text('Urgent'),
],
)
),
),
onTap: () {
setState(() {
if (isUrgent=='true'){
isUrgent = 'false';}
else
{isUrgent= 'true';
}
});
},
),
),
],
),
)),

You are using Expanded widget where it cannot be used. The parent of an Expanded widget can only be a Flex widget. Expanded widget has to be a child of Row, Column or Flex widget.
Therefore you will have to remove Expanded widget from all places where the parent of Expanded Widget is not either a Row, Column or Flex. For example in the code below, Expanded widget is a child of FlatButton so you will have to remove the Expanded from here.
FlatButton(
child:
InkWell(
>>>>>>>>> child: Expanded( <<<<< REMOVE FROM HERE
child: Container(
// color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.battery_charging_full),
Text('Energy'),
],
)
),
),
onTap: () { },
),
),
Please refer to Flutter docs : Expanded class
Expanded
A widget that expands a child of a Row, Column, or Flex so that the
child fills the available space.
Using an Expanded widget makes a child of a Row, Column, or Flex
expand to fill the available space along the main axis (e.g.,
horizontally for a Row or vertically for a Column). If multiple
children are expanded, the available space is divided among them
according to the flex factor.
An Expanded widget must be a descendant of a Row, Column, or Flex, and
the path from the Expanded widget to its enclosing Row, Column, or
Flex must contain only StatelessWidgets or StatefulWidgets (not other
kinds of widgets, like RenderObjectWidgets).

Related

Flutter: Expanded IconButton still shows under the Container

AnimatedContainer(
...
child: Container(
child: Column(
children: [
Row(
children: [
Container(
width:60,
height:50,
color: Colors.black,
),
],
),
Expanded(
child: GestureDetector(
onTap: () {
print('what');
},
child: Container(
height: 50,
child: Column(
children: [
Expanded(
child: Text('asdf'),
),
Expanded(
child: IconButton(
icon: Icon(Icons.ac_unit),
onPressed: () {},
),
I have this AnimatedContainer widget here. My Text() widget and RaisedButton widget are hidden inside the box. They appear as the AnimatedContainer expand. However, my IconButton doesn't.
Also, Icon widget also stays like IconButton widget. How can I make it appear when the AnimatedContainer is stretched like the Text widget?
I've modified your code, hope this is what u want.
class _RowStructureState extends State<RowStructure> {
bool pressed = false;
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
setState(() {
pressed = !pressed;
});
print(pressed);
},
child: Column(children: <Widget>[
AnimatedContainer(
height: pressed ? 120 : 50,
color: Colors.green,
duration: Duration(seconds: 1),
child: Stack(
children: [
Container(
height: 50,
width: 50,
color: Colors.black,
),
Positioned(
bottom:0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text('asd'),
IconButton(
padding: EdgeInsets.all(0),
icon: Icon(Icons.ac_unit,),
onPressed: pressed?(){}:null,
),
],
),
)
],
),
)
]),
);
}
}

How can I have two buttons in the bottom using align widget inside the center and column widgets?

I am trying to have a grouped button with two individuals and place them in the bottom. It is a login screen so there are other things.
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 75.0,
),
Text('Login'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.orange,
onPressed: () {
print('login');
},
),
RaisedButton(
onPressed: () {
print('signup');
},
),
],
),
],
),
),
),
);
}
}
I've been trying with like align bottom and stuffs. But with Row(), it does not work with Center + Column widget. How can I send these two buttons to the bottom of the Center widget?
There are multiple ways to do this. One of them is to use the Spacer widget:
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 75.0,
),
Spacer(),
Text('Login'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.orange,
onPressed: () {
print('login');
},
),
RaisedButton(
onPressed: () {
print('signup');
},
),
],
),
],
),
),
),
);
Another one would be to reverse the column and start from the bottom, but most probably the side effects are not wanted.
Also, one option would be to divide the whole screen into fixed height partitions with the help of MediaQuery.of(context).size.height value so that your buttons are always at the bottom.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
body: SafeArea(
child: Center(
child: Column(
children: <Widget>[
SizedBox(
height: 75.0,
),
Text('Login'),
Expanded(
child:Container
(
alignment: Alignment.bottomCenter,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.orange,
onPressed: () {
print('login');
},
),
RaisedButton(
onPressed: () {
print('signup');
},
),
],
),
)
)
],
),
),
),
);
}

Flutter - Put the expand arrow at the end of the last line of the text

Basically I want to achieve the similar thing as this post Flutter: How to hide or show more text within certain length. However, I need to replace "show more" with an arrow and the arrow should be at the end of the last line of the collapsed text (not below it). I checked https://pub.dev/packages/expand_widget and https://pub.dev/packages/expandable these two packages, but they didn't seem to satisfy my requirements.
Could anyone help me with it? Thanks!
I think it should work for you!
Row(
children: [
Expanded(
child: Text("your text or widget"),
),
Icon(Icons.keyboard_arrow_down)
],
);
Just have an arrorw_down icon. When clicked change a boolean in setState(). In the widget tree just check if it's true, show something, else don't.
Switch between arrow_up/down depending on the boolean.
Expanded(
flex: 2,
child: InkWell(
onTap: () {
setState(() {
isBubbleExpanded = !isBubbleExpanded; // should expand?
});
},
child: Padding(
padding: EdgeInsets.all(3),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Center(
child: Icon(isBubbleExpanded
? Icons.keyboard_arrow_up
: Icons.keyboard_arrow_down),
),
],
),
],
),
),
),
));
}
Then somewhere else in the tree:
if (isBubbleExpanded)
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.all(2),
child: Center(),
),
),
Expanded(
flex: 2,
child: Center(
child: IconButton(
icon: const Icon(CupertinoIcons.info),
onPressed: () {
Navigator.of(context).pushNamed(
SomeScreen.routeName,
arguments: widget.document,
);
},
),
),
),
],
),

How to align a widget to the right of a dynamic centered widget in Flutter?

I have a text widget in the center that has a dynamic width. However, I want to add in a widget to the right of this text widget.
Because this center text wiget has a dynamic width, I cannot use absolute positioning widgets such as Align or the Position Widget. I am looking for something similar to RelativeLayout in Android.
Widget body() {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Center text'),
FlatButton(
child: Text('next'),
onPressed: () {},
),
],
),
);
}
With #Igors method I can end with a center widget with a button on each end evenly spaced. I am aiming for the button to be to the right of.
Widget body() {
return Container(
child: Row(
children: <Widget>[
Expanded(
child: FlatButton(
child: Text('next'),
onPressed: () {},
),
),
Container(color: Colors.red, child: Text('test')),
Expanded(
child: FlatButton(
child: Text('next'),
onPressed: () {},
),
),
],
),
);
}
Edit: Solved through the use of Sized Box on each side of the centered widget 1.
Row(
children: <Widget>[
Expanded(
child: Container(
color: Colors.green
),
),
Container(
color: Colors.red,
child: Text('test')
),
Expanded(
child: Container(
color: Colors.blue
),
),
],
)
Use the Widget Row and add the text widget in a Container Widget.
And add margin for the Container

Is there a way to align a widget to the far right of a row in Flutter?

I have a row in Flutter with two widgets. I'm trying to keep the first widget centered in the middle of the screen and the second widget forced to the far right of the screen.
I've tried using Spacer(). This results in the app returning a blank screen.
I've also tried using Expanded. This sends the second widget off the screen completely.
Trying mainAxisAlignment: MainAxisAlignment.spaceBetween did not seem to have any effect.
#override
Widget build(BuildContext context) {
return new Container(
height: MediaQuery.of(context).size.height,
child: SingleChildScrollView(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Container(
child: new GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: Column(
children: <Widget>[
SizedBox(height: 40.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Column(
children: <Widget>[
new Container(
child: Row(
mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(),
Container(
child: Text(
'Profile',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Lato',
color: Colors.white,
fontSize: 50.0,
fontWeight: FontWeight.w700,
),
),
),
Container(
child: IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
size: 30.0,
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => OnBoarding()),
);
}),
),
]),
),
),
],
),
],
),
You can use a Row with an Expanded child that contains a Stack. Centre your text with Center and position the icon with Positioned, like so:
[...]
child: Column(
children: <Widget>[
SizedBox(height: 40.0),
Row(
children: <Widget>[
Expanded(
child: Stack(
children: [
Center(
child: Text(...),
),
),
Positioned(
right: 8,
child: IconButton(...),
[...]
Simply just add Spacer() between your main text and the Icon you want to the far right.
For example:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
),
Text(
'Random test text',
style: TextStyle(color: Colors.white),
),
Spacer(),
IconButton(
icon: Icon(Icons.more_vert_rounded),
color: Colors.white,
onPressed: () {},
),
],
)
I hope this helps you. And I hope the format of the code is readable. Still getting a hang of stackoverflow comments
I did this and worked in my project
child:Row(
**crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end,**
children: [
Icon(MaterialCommunityIcons.comment_outline),
Text("0"),
Icon(Icons.favorite_border),
Text("0"),
],
),
I needed align Icons and Text at right in Row widget
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.end
children: [ // put your widget list and be happy ]
)
)
enter image description here
Use a row with this following structure:
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(),
Container(
child: Text(
'Profile',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Lato',
color: Colors.white,
fontSize: 50.0,
fontWeight: FontWeight.w700,
),
),
),
Container(
child: IconButton(
icon: Icon(
Icons.settings,
color: Colors.white,
size: 30.0,
),
),
),
]
),
what will happen is that the spaceBetween property will divide available space equally between the widgets in the row, so I put an empty Container, and this will force the Text widget to be in the middle of the row and the IconButton in the far end as you desire.
I noticed in your code snippet that you have a Column with a single Row which again contains a single Column , you should eliminate this redundancy to optimize your code and make it easier to debug:
Have you tried setting the mainAxisAlignment of the row to mainAxisAlignment.center?
Imo the easiest way to do this is to create a row with 2 children: The first child is an Expanded Row with all your "main" widgets. The second child is your widget which must be aligned to the end.
Row(
children: [
Expanded(
child: Row(
children: [...mainWidgets...],
),
),
...endWidget...
],
),
Note that Expanded is space-greedy. If you use e.g. MainAxisAlignment.center for your Expanded Row, then your children are drawn across the whole avialable width. If this is not to your liking, Id suggest to wrap the Expanded-Row (not Expanded) inside a Container with "constraints: BoxConstraints(maxWidth: 500)". Obviously Expanded shouldnt be Constrained.
Achieve using Expanded & Align like below inside Row:
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
...some other widgets,
Expanded(
//Expanded will help you to cover remaining space of Row
flex: 1,
child: Align(
//Align with alignment.centerRight property will move the child to righteous inside Expanded
alignment: Alignment.centerRight,
child: const Icon(Icons.arrow_back),
),
),
],
),
Note, the Expanded has to be just inside the Row children: <Widget>[],
othewise suppose you've put the GestureDetector inside Row children: <Widget>[], and inside GestureDetector you have put your Expanded, then it won't
work.
Hope this would help many one.