Abed's answer stated the correct solution to your specific question. However, there are many other tricky issues to solve when creating a bottom sheet. Here is my complete working bottom sheet creator function, which will hopefully help someone.
import 'package:flutter/material.dart';
Future Function() openBottomSheet(BuildContext context, Widget child,
{String? title}) {
return () => showModalBottomSheet(
// Don't let bottom sheet extend past the top of the safe area
useSafeArea: true,
context: context,
// Round the top of the bottom sheet
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
// Add scrollbar when necessary
isScrollControlled: true,
builder: (context) => ScrollableWidget(
child: Container(
// Move bottom sheet above on-screen keyboard, if keyboard is open
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Stack(
children: [
// Add back button at top left of bottom sheet (since it's
// not obvious that sheet can be swiped down to close it)
const BackButton(),
Padding(
// Pad the main widget (larger padding on the top to leave
// space for the back button)
padding: const EdgeInsets.fromLTRB(20.0, 35.0, 20.0, 25.0),
child: Column(
children: [
// Make content full-width, so that main widget is
// centered even if it doesn't expand
Row(
mainAxisSize: MainAxisSize.max,
children: const [SizedBox(height: 0)],
),
// Add title text to top of bottom sheet, if provided
title == null
? Container()
: Column(
children: [
Text(
title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
],
),
// Add the main widget
child,
],
),
),
],
),
),
),
);
}
/// A scrollable widget with a scrollbar that is shown when necessary
class ScrollableWidget extends StatefulWidget {
const ScrollableWidget({super.key, required this.child});
final Widget child;
@override
State<ScrollableWidget> createState() => _ScrollableWidgetState();
}
class _ScrollableWidgetState extends State<ScrollableWidget> {
final controller = ScrollController();
@override
Widget build(BuildContext context) {
return Scrollbar(
thumbVisibility: true,
thickness: 15,
radius: const Radius.circular(8),
controller: controller,
child: SingleChildScrollView(
// Same controller must be used on Scrollbar and SingleChildScrollView
controller: controller,
child: widget.child,
),
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
}
Padding
element as the last child ofColumn
and set its padding aspadding: MediaQuery.of(context).viewInsets
– Durance