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?




