The code below lays out a chart in which I\'d need to achieve for the chart to be expanded in both vertical (height) and horizontal (width) direction. The suggested method (e.g.
There is a better way than nesting Row
, Expanded
and Column
widget. You can use the Container
widget with Constraints
to BoxConstraints.expand()
.
Example Code:
Widget build(BuildContext context) {
return Container(
constraints: BoxConstraints.expand(),
child: FutureBuilder(
future: loadImage(),
builder: (BuildContext context, AsyncSnapshot<ui.Image> snapshot) {
switch(snapshot.connectionState) {
case ConnectionState.waiting :
return Center(child: Text("loading..."),);
default:
if (snapshot.hasError) {
return Center(child: Text("error: ${snapshot.error}"),);
} else {
return ImagePainter(image: snapshot.data);
}
}
},
),
);
}
Here is a reduced test case for the issue you are seeing. The solution is to give your Row
a crossAxisAlignment
of CrossAxisAlignment.stretch
. Otherwise it will try to determine the intrinsic height of your CustomPaint
which is zero because it doesn't have a child.
import 'package:flutter/material.dart';
// from https://stackoverflow.com/questions/45875334/how-to-achieve-expansion-of-a-widget-in-both-vertical-height-and-horizontal-w
class MyCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// NOT using crossAxisAlignment: CrossAxisAlignment.stretch => width = 222.0, height=0.0
// using crossAxisAlignment: CrossAxisAlignment.stretch => width = 222.0, height=560.0
print("width = ${size.width}, height=${size.height}");
canvas.drawRect(Offset.zero & size, new Paint()..color = Colors.blue);
}
@override
bool shouldRepaint(MyCustomPainter other) => false;
}
void main() {
runApp(new MaterialApp(
home: new Scaffold(
body: new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text('Above Paint'),
// Expanded - because we are in Column, expand the
// contained row's height
new Expanded(
child: new Row(
// The crossAxisAlignment is needed to give content height > 0
// - we are in a Row, so crossAxis is Column, so this enforces
// to "stretch height".
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Text('Left of Paint'),
// Expanded - because we are in Row, expand the
// contained Painter's width
new Expanded(
child: new CustomPaint(
painter: new MyCustomPainter(),
),
),
new Text('Right of Paint'),
],
),
),
new Text('Below Paint'),
],
)
),
));
}
For those who struggled to get gradient together with Material behaviour:
return new Stack(
children: <Widget>[
new Material(
elevation: 10,
borderRadius: new BorderRadius.all(new Radius.circular(30.0)),
color: Colors.transparent,
child: new Container(
constraints: BoxConstraints.expand(height: 50),
),
),
new Container(
constraints: BoxConstraints.expand(height: 50),
decoration: BoxDecoration(
borderRadius: new BorderRadius.all(new Radius.circular(30.0)),
gradient: new LinearGradient(
colors: [color1, color2],
begin: Alignment.topCenter,
end: Alignment.bottomCenter),
),
child: new FloatingActionButton.extended(
backgroundColor: Colors.transparent,
foregroundColor: Colors.transparent,
highlightElevation: 0,
elevation: 0,
onPressed: () {
onPressed();
},
label: new Text(this.caption,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.body1),
),
)
],
)
Use SizedBox.expand
:
SizedBox.expand(
child: YourWidget() // Could be anything like `Column`, `Stack`...
)