Dialog with flexible height and scrollable content
You can use Column and Flexible.
void showCustomDialog(BuildContext context, String message) async {
await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: Container(
width: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text("Description 1",
style: TextStyle(fontWeight: FontWeight.bold)),
SizedBox(height: 8),
Flexible(
child: SingleChildScrollView(
child: Text(message),
),
),
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text("OK"),
)
]),
),
);
},
);
}
lyessmecano
Updated on December 29, 2022Comments
-
lyessmecano over 1 year
I am trying to create a custom Dialog that will be as short as its content up until this content is too high, at which point it should be scrollable.
Here is what I'm starting with:
showDialog( context: context, useSafeArea: true, barrierDismissible: true, useRootNavigator: false, builder: (context) => Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), elevation: 3, backgroundColor: Theme.of(context).colorScheme.surface, child: Padding( padding: const EdgeInsets.all(20.0), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text(lorem(paragraphs: 1)), SizedBox(height: 20), ElevatedButton( onPressed: () { Navigator.pop(context); }, child: Text('OK'), ), ], ), ), ), );
This gives me the following result:
Now if I add more text to make it taller, the height of the dialog adapts:
If we go even further, at some point, we go into overflow:
So I wrap my text in a SingleChildScrollView but that's not enough to fix the overflow, so I wrap the SingleChildScrollView into an Expanded:
Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded( child: SingleChildScrollView( child: Text(lorem(paragraphs: 30)), ), ), SizedBox(height: 20), ElevatedButton( onPressed: () { Navigator.pop(context); }, child: Text('OK'), ), ], )
This time the text scrolls as expected, and the dialog uses all the vertical space it can but not more:
But now if I reduce the text size again the that it's shorter than the available space, the dialog still takes up all the vertical space and leaves a gap between the text and the button:
And obviously, that's not what I want. Any idea how I can make this work without calling onto MediaQuery witchcraft?
-
Taleb almost 3 yearsPlease join the LinkedIn group and share your Question link there for other developers to be notified: linkedin.com/groups/12438453
-
-
lyessmecano almost 3 yearsBut if I do that, the button scrolls with the text, and I want the button to stick to the bottom of the dialog. Only the text should scroll.
-
Harry almost 3 years@Sebastian : You can take out of the column and make another
Row()
for the button. -
Harry almost 3 yearsThe scrollable text only should be in the column which is wrapped by
SingleChildScrollView
. -
lyessmecano almost 3 yearsThank you, replacing the Expanded by a Flexible worked wonders.