SingleChildScrollView inside Row
I found a solution by wrapping the Wrap in a ConstrainedBox (instead of a row) for which the minWidth is the width of the screen.
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
padding: const EdgeInsets.all(kPaddingMainContainer),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Title', style: Theme.of(context).textTheme.title)
],
),
Padding(
padding: const EdgeInsets.only(top: 10),
),
Expanded(
child: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width,
),
child: Wrap(
alignment: WrapAlignment.center,
runSpacing: 20.0, // distance between rows
spacing: 30.0, // distance between chips
children: _getWidgets(),
),
),
),
),
]),
),
),
);
}
This fixed my issue and I can now scroll the Wrap widget only by tapping anywhere on the screen, while the first row with the title stays fixed.
skuallpa
Updated on December 12, 2022Comments
-
skuallpa over 1 year
I have a layout made of a Column, one of its elements being a row (so that it takes the full width of the screen). Inside that row, I have a wrap, which content is pretty big and that I want to put inside a SingleChildScrollView.
@override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Container( padding: const EdgeInsets.all(kPaddingMainContainer), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('Title', style: Theme.of(context).textTheme.title) ], ), Padding( padding: const EdgeInsets.only(top: 10), ), Row( children: <Widget>[ Expanded( child: SingleChildScrollView( child: Wrap( alignment: WrapAlignment.center, runSpacing: 20.0, // distance between rows spacing: 30.0, // distance between chips children: _getWidgets(), ), ), ), ], ), ], ), ), ), ); }
With this code, I can't get the SingleChildScrollView to make the wrap scrollable. Instead, I got a RenderFlex overflowed error.
However, if I extract the wrap from the Row, as follow:
@override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Container( padding: const EdgeInsets.all(kPaddingMainContainer), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('Title', style: Theme.of(context).textTheme.title) ], ), Padding( padding: const EdgeInsets.only(top: 10), ), Expanded( child: SingleChildScrollView( child: Wrap( alignment: WrapAlignment.center, runSpacing: 20.0, // distance between rows spacing: 30.0, // distance between chips children: _getWidgets(), ), ), ), ]), ), ), ); }
Then, the scroll is working.
However, now the wrap doesn't expand to full width anymore, what I want.
How to use the SingleChildScrollView inside a Row ?
PS: I don't want to wrap the Column in a SingleChildScrollView as I want my title to stay fixed and only the wrap below to scroll.
-
Andrey Turkovsky almost 5 yearsWhy exactly do you need to use
Row
? -
Julien Lachal almost 5 yearshow about Slivers?
-
skuallpa almost 5 years@AndreyTurkovsky: I experienced that if I don't put the wrap inside the row, it doesn't expand to full width, thus the user has to scroll by touching inside the area of the wrap only, what is not very user friendly. He should be able to scroll by touching anywhere on the horizontal axis (around the wrap). So that's why I wrapped it in a Row.
-
skuallpa almost 5 years@JulienLachal: I didn't consider this option yet, I thought it should be possible with a SingleChildScrollView only. Is that the way to go?
-
Julien Lachal almost 5 yearsAFAIK the
SingleChildScrollView
is useful when you want to scroll through more than the size of the screen, instead of using a ListView and be stuck when it occupies the full height of the phone. It also allows you to keep all the widgets "alive" when they appear outside of the viewport. Take a look at the Flutter video
-