-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Description
When using the technique listed here, under the heading "Expanding content to fit the viewport": https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html,
a Column widget works very well, but a Wrap does not. Is there something maybe missing from the way the Wrap widget lays itself out that could be improved to act more like a Column?
Essentially, the following sample shows the problem. If you run this app on a device, it should start out with a view that can be scrolled so all children are accessible. Hitting the button at the top to switch to using a Wrap will cause an Overflow.
Switching back to a Column, you can scroll again, and if you change the number in the text field to a smaller number, you can get the Wrap widget to work well as long as no Overflow happens.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: WrapHomePage(),
);
}
}
class WrapHomePage extends StatefulWidget {
const WrapHomePage();
@override
_WrapHomePageState createState() => _WrapHomePageState();
}
class _WrapHomePageState extends State<WrapHomePage> {
bool _useColumn = true;
int _numTexts = 8;
List<Widget> _buildTexts(int numTexts) {
List<Widget> texts = [];
for (int i=0; i<numTexts; i++) {
texts.add(Padding(
padding: const EdgeInsets.only(top: 24.0),
child: Text(
"Hello, this is some long text. It can go on and on. This test is to make sure we can scroll"),
));
}
return texts;
}
@override
Widget build(BuildContext context) {
final texts = _buildTexts(_numTexts);
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(24),
child: LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minHeight: constraints.maxHeight,
),
child: IntrinsicHeight(
child: DefaultTextStyle(
style: TextStyle(fontSize: 20, color: Colors.black),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
FlatButton(
onPressed: () {
setState(() {
_useColumn = !_useColumn;
});
},
child: Text(_useColumn ? "Switch to Wrap!" : "Switch to Column!", style: TextStyle(fontSize: 20, color: Colors.black))
),
if (_useColumn)
Column(
key: ValueKey("header"),
children: texts,
)
else
Wrap(
key: ValueKey("header"),
children: texts,
),
Expanded(
key: ValueKey("middle"),
child: Container(
color: Colors.red,
child: Center(
child: TextField(
onChanged: (value) {
setState(() {
_numTexts = int.parse(value);
});
},
)
),
)
),
Padding(
key: ValueKey("footer"),
padding: const EdgeInsets.only(top: 24.0),
child: Column(
children: [
Text("Final message")
],
),
)
],
),
),
),
)
);
}
),
)
)
);
}
}