Flutter's Flexible Behavior - flutter

I want the blue to be full.
But it only spreads up to half.
https://i.stack.imgur.com/UQsiB.png
class TestScene extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.red,
child: const Text('1'),
),
),
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.blue,
child: const Text('1234567890123456789012345678901234567890'),
),
),
],
),
);
}
}
The reverse will also fail.
https://i.stack.imgur.com/rf00I.png
In both cases, it's nice.
https://i.stack.imgur.com/21ORb.png

This is a way ! (To take remain space)
String one='1',two='1234567890123456789012345678901234567890';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
backgroundColor:Colors.white,
body: Row(
mainAxisSize:MainAxisSize.max,
children: <Widget>[
one.length>=two.length ?
Expanded(
child: Container(
color: Colors.red,
child: Text(one),
),
):Container(
color: Colors.red,
child: Text(one),
),
two.length>=one.length ?
Expanded(
child: Container(
color: Colors.blue,
child: Text(two),
),
):Container(
color: Colors.blue,
child: Text(two),
),
],
),
);
}
Or to maintain equal size with colors simply use Expanded in both widgets

Wrap the one that you want to fill the space by Expanded. If you want both red and blue to fill the row, wrap both of them with Expanded and give them their own ratio with the flex property
class TestScene extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Row(
children: <Widget>[
Container(
color: Colors.red,
child: const Text('1'),
),
Expanded(
child: Container(
color: Colors.blue,
child: const Text('1234567890123456789012345678901234567890'),
),
),
],
),
);
}
}

Related

create scaffold with global container on top

I need a global area on top to show some ads. This are remains the same for all pages and widgets. So far I've got this:
Stack(
children: [
Column(
children: <Widget>[
Container(
color: Theme.of(context).primaryColor,
width: double.infinity,
height: bannerHeight,
child: MY_BANNER,
),
Expanded(child: child!), // this has to be dynamic
],
),
],
);
What's the problem? It creates an extra padding for the AppBar that I don't know how to remove:
Instead of creating a space on top of AppBar you can put your banner ads below it. For this you can make a custom MyAppBar widget and use this custom widget inside the Scaffold.
class MyAppBar extends StatelessWidget with PreferredSizeWidget {
final String title;
MyAppBar(this.title) : preferredSize = const Size.fromHeight(110);
#override
final Size preferredSize;
#override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.max,
children: [
AppBar(
title: Text(
title,
),
),
Center(
child: Container( // Place your ad here
color: Colors.red,
width: MediaQuery.of(context).size.width / 2,
height: 50,
),
),
],
);
}
}
and use it like
Scaffold(
appBar: MyAppBar(
"Hello App",
),
),
return Scaffold(
body: SafeArea(
child: Column(
children: [
Row(
children: [
Expanded(
child: MY_BANNER
),
],
),
Expanded(child: child!),
],
),
),
);

How to configure a container in flutter to use the same height of an other children in the same row or column

I like to increase the height of the widget "B" so the orange color use the same space like the green color. I have added a code example.
If a added Extended() like Expanded(Container(Text('B'))) the full horizontal space of the screen is used.
If a added Extended() like Column(Expanded(Container(Text('B')))) the full vertical space of the screen is used.
Does someone has a hint?
Thank you in advance!
Gretings
Michael
Problem:
Goal:
Code:
import 'package:flutter/material.dart';
void main() {
runApp(DemoX());
}
class DemoX extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color: Colors.red,
child: Container(
color: Colors.green,
child: Text('A1\nA2'),
),
),
Container(
color: Colors.orange,
child: Text('B'),
),
],
),
),
),
);
}
}
Screenshot
Code:
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: IntrinsicHeight(
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Colors.green,
child: Text('A1\nA2'),
),
Container(
color: Colors.orange,
child: Text('B'),
),
],
),
),
),
);
}

Align text in centre of screen

I am trying to use Expand widget in Column so user can tap in any position of screen to increase counter, but there is an issue in alignment of text in crossAxisAlignment and mainAxisAlignment of the column it didn't apply on Expand widget as the following
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black12,
body: SafeArea(
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () {
setState(() {
i++;
print(i);
});
},
child: Text(
i.toString(),
style: TextStyle(fontSize: 50.0, color: Colors.blueAccent),
textAlign: TextAlign.center,
),
),
),
],
),
),
),
),
);
You went with the wrong approach because you can't Center an Expanded because Expanded takes the entire available space inside Row or Column in your case Column with single Widget inside children the GestureDetector. Here is one of a solution for what you want to achieve
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black12,
body: SafeArea(
child: Center(
child: Stack(
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: GestureDetector(
onTap: () {
setState(() => i++;);
},
),
),
],
),
Align(
alignment: Alignment.center,
child: Text(
'$i',
style: TextStyle(fontSize: 50.0, color: Colors.blueAccent),
),
),
],
),
),
),
);
}
another solution using FlatButton inside SizedBox.expand()
so you don't need to fight with a single child column.
class _MyAppState extends State<MyApp> {
int i = 0;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black12,
body: SafeArea(
child: SizedBox.expand(
child: FlatButton(
onPressed: () {
setState(() {
i++;
print(i);
});
},
child: Text(
i.toString(),
style: TextStyle(fontSize: 50.0, color: Colors.blueAccent),
),
),
),
),
),
);
}
}

Can't find correct layout option for how to use ListView in a custom Widget

I am trying to extract re-use a simple widget that is then referenced in parent widget. The custom widget simply uses a row to layout a textField and a button, and below this I Want to have a listview showing items. I then embed in the customwidget in parent, but it continually throws Error. I have not figured out how to get the custom widget working where I can use ListView or column layout inside. Below is the 2 simplified widgets that demo the issue.
Here is the parent widget, which is where I call the custom widget PlayListControl()
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('My Playlists'),
),
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20),
child: Text('Test'),
),
PlayListControl(),
],
),
),
drawer: SideDrawer(),
);
}
}
And here is the playlistcontrol widget.
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
child: TextField(),
),
ButtonTheme(
minWidth: 30,
child: RaisedButton(
textColor: Colors.white,
child: Text('add'),
onPressed: () {},
)),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
Text('Widget 1'),
Text('Widget 2'),
],
),
)
],
),
);
}
}
No matter what I try, it always complains about layout issue related to height. I would have thought wrapping the ListView in Expanded would solve the issue, but it doesn't. Only if I use a container and specify height do I not get the errors, but I want to use whatever available space there is.
How can I get this playlistcontrol() widget to properly render inside a parent control?
you forgot to wrap the first container of PlayListControl in Expanded widget..
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: Text('My Playlists'),
),
body: Container(
child: Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
textDirection: TextDirection.ltr,
children: <Widget>[
Container(
alignment: Alignment.center,
margin: EdgeInsets.all(20),
child: Text('Test'),
),
PlayListControl(),
],
),
),
));
}
}
class PlayListControl extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Expanded(
child: Container(
margin: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: 200,
child: TextField(),
),
ButtonTheme(
minWidth: 30,
child: RaisedButton(
textColor: Colors.white,
child: Text('add'),
onPressed: () {},
)),
],
),
),
Expanded(
child: ListView(
children: <Widget>[
Text('Widget 1'),
Text('Widget 2'),
],
),
)
],
),
),
);
}
}

Flutter Layout Row / Column - share width, expand height

I'm still having a bit of trouble with the layouting in Flutter.
Right now I want to have the available space shared between 3 widgets, in a quadrant layout.
The width is evenly shared (this works fine via 2 Expanded widgets in a Row), but now I also want the height to adjust automatically so widget3.height == widget1.height + widget2.height.
If the content of widget3 is larger, I want widget1 and widget2 to adjust their height and vice versa.
Is this even possible in Flutter?
Have a look at IntrinsicHeight; wrapping the root Row should provide the effect you're looking for:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: Text('Rows & Columns')),
body: RowsAndColumns(),
),
);
}
}
class RowsAndColumns extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 100.0),
child: IntrinsicHeight(
child: Row(crossAxisAlignment: CrossAxisAlignment.stretch, children: [
Expanded(
child: Column(children: [
Container(height: 120.0, color: Colors.yellow),
Container(height: 100.0, color: Colors.cyan),
]),
),
Expanded(child: Container(color: Colors.amber)),
]),
),
);
}
}
Adjusting the heights in the containers in the column cause the container on the right to resize to match:
https://gist.github.com/mjohnsullivan/c5b661d7b3b4ca00599e8ef87ff6ac61
I think that you can set the height of the row instead, then you only must to set the height of you column containers, and with the crossAxisAlignment: CrossAxisAlignment.stretch the second row will be expand occupying his parent height:
Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Column(
children: [
Expanded(
// If you don't have the height you can expanded with flex
flex: 1,
child: Container(
height: 50,
color: Colors.blue,
),
),
Expanded(
flex: 1,
child: Container(
height: 50,
color: Colors.red,
),
)
],
),
),
Expanded(
child: Container(
color: Colors.yellow,
),
)
],
)
Since IntrinsicHeight is considered relatively expensive, it's better to avoid it. You can use Table with verticalAlignment: TableCellVerticalAlignment.fill in the largest TableCell.
Please note that if you use .fill in all cells, the TableRow will have zero height.
Table(children: [
TableRow(children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
alignment: Alignment.center,
color: Colors.blue,
child: Text('Widget 1'),
),
Container(
alignment: Alignment.center,
color: Colors.green,
child: Text('Widget 2'),
),
],
),
TableCell(
verticalAlignment: TableCellVerticalAlignment.fill,
child: Container(
alignment: Alignment.center,
color: Colors.orange,
child: Text('Widget 3'),
)),
]),
]),
I'm new to flutter. Please correct me if I'm doing something wrong here. I think It can also be achieved using setState((){}) without using IntrinsicHeight.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
double h1 = 100;
double h2 = 200;
double h3;
setState(() {
h3 = h1 + h2;
});
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 100.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
children: [
Container(
color: Colors.green,
height: h1,
),
Container(
color: Colors.orange,
height: h2,
)
],
),
),
Expanded(
child: Container(
color: Colors.yellow,
height: h3,
),
)
],
),
),
),
),
);
}
}
Find image here
Code can also be found here: https://gist.github.com/Amrit0786/9d228017c2df6cf277fbbaa4a6b20e83
if you have used the expanded inside Row and facing for full height issue then just wrap the expanded child with Align widget.