Reputation: 803
I tried a few different approaches but I can't get this to work. The layout I want to achieve is really simple and it's a breeze to implement in native Android:
I tried to use SingleChildScrollView
, but it doesn't seem to work inside a Column
. Maybe I'm doing something wrong or I'm not using the right widgets...
My result:
Scaffold(
body: Column(
children: <Widget>[
Container(
height: 100.0,
color: Colors.blue,
),
SingleChildScrollView(
child: Container(
color: Colors.red,
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text('Red container should be scrollable'),
Container(
width: double.infinity,
height: 700.0,
padding: EdgeInsets.all(10.0),
color: Colors.white.withOpacity(0.7),
child: Text('I will have a column here'),
)
],
),
),
),
],
),
)
Upvotes: 79
Views: 46128
Reputation: 31
If you don't want to expand your column to maximal size, wrap your SingleChildScrollView
into Flexible
:
return Column(
mainAxisSize: MainAxisSize.min,
children: [
//header
Container(
color: Colors.red,
height: 50,
child: const Text("Header"),
),
Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
//top
Container(
color: Colors.blue,
height: 100,
child: const Text("Top"),
),
Container(
color: Colors.yellow,
height: 5000,
),
//bottom
Container(
color: Colors.green,
height: 100,
child: const Text("Bottom"),
),
],
),
)),
//footer
Container(color: Colors.red, height: 50, child: const Text("Footer")),
],
);
Upvotes: 3
Reputation: 2292
I think that maybe after a year you have managed to do that.
But for others searching for the same problem, the easiest way is to wrap the SingleChildScrollView
inside an Expanded
widget.
Widget build(BuildContext context) =>
Scaffold(
body: Column(
children: <Widget>[
Container(
height: 100.0,
color: Colors.blue,
),
Expanded(
child: SingleChildScrollView(
child: Container(
color: Colors.red,
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text('Red container should be scrollable'),
Container(
width: double.infinity,
height: 700.0,
padding: EdgeInsets.all(10.0),
color: Colors.white.withOpacity(0.7),
child: Text('I will have a column here'),
)
],
),
),
),
),
],
),
);
Upvotes: 203
Reputation: 803
I managed to implement a working layout using a Stack
, the only down-side being that if I have a TextField
and I scroll down, the cursor 'bubble' shows up above my top container... which is kind of ugly. The order of my widgets in the Stack
doesn't affect this.
Widget build(BuildContext context) =>
Scaffold(
body: Stack(
children: <Widget>[
Container(
height: 100.0,
color: Colors.blue,
),
Container(
margin: EdgeInsets.only(top: 100.0),
child: SingleChildScrollView(
child: Container(
color: Colors.red,
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Container(
width: double.infinity,
height: 700.0,
padding: EdgeInsets.all(10.0),
color: Colors.white.withOpacity(0.7),
child: TextField(),
)
],
),
),
),
),
],
),
);
Upvotes: 1
Reputation: 1807
The problem is that Column
widget does not support scrolling. In order to make it work you may switch to ListView
, but current implementation lack of some sort of header for sections. In order to get them you may use sticky_headers package like that:
Widget build(BuildContext context) => Scaffold(
body: new ListView.builder(
itemCount: 1,
padding: EdgeInsets.zero,
itemBuilder: (context, index) {
return new StickyHeader(
header: Container(
height: 100.0,
color: Colors.blue,
),
content: Container(
color: Colors.red,
padding: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text('Red container should be scrollable'),
Container(
width: double.infinity,
height: 700.0,
padding: EdgeInsets.all(10.0),
color: Colors.white.withOpacity(0.7),
child: Text('I will have a column here'),
)
],
),
));
}));
Upvotes: 3