Scroll through Flutter Bottom Sheet
Almost the same solution like this one but without the unnecessary layers of gesture detectors etc.
The important part is the expand: false,
in DraggableScrollableSheet
, because it defaults to true. This causes the bottom sheet to expand to full height in default config. With this set to false there is no need to wrap the bottom sheet with two gesture detectors to detect the outside tap.
Also in this case only one shape is required.
showModalBottomSheet(
context: context,
isScrollControlled: true,
isDismissible: true,
shape: const RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(top: Radius.circular(16))),
builder: (context) => DraggableScrollableSheet(
initialChildSize: 0.4,
minChildSize: 0.2,
maxChildSize: 0.75,
expand: false,
builder: (_, controller) => Column(
children: [
Icon(
Icons.remove,
color: Colors.grey[600],
),
Expanded(
child: ListView.builder(
controller: controller,
itemCount: 100,
itemBuilder: (_, index) {
return Card(
child: Padding(
padding: EdgeInsets.all(8),
child: Text("Element at index($index)"),
),
);
},
),
),
],
),
),
);
If you want a model bottom sheet that can be scrolled.
You can use the isScrollControlled
attribute of showModalBottomSheet to achieve the effect.
If you want a persistent bottom sheet that can be scrolled.
You can use the DraggableScrollableSheet
Example:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('DraggableScrollableSheet'),
),
body: SizedBox.expand(
child: DraggableScrollableSheet(
builder: (BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.blue[100],
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
},
),
);
},
),
),
);
}
}
Here is the official video from the Flutter team.
A live demo on DartPad can be found here.
I've found a solution implementing the code below
void _showBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) {
return GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: Container(
color: Color.fromRGBO(0, 0, 0, 0.001),
child: GestureDetector(
onTap: () {},
child: DraggableScrollableSheet(
initialChildSize: 0.4,
minChildSize: 0.2,
maxChildSize: 0.75,
builder: (_, controller) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(25.0),
topRight: const Radius.circular(25.0),
),
),
child: Column(
children: [
Icon(
Icons.remove,
color: Colors.grey[600],
),
Expanded(
child: ListView.builder(
controller: controller,
itemCount: 100,
itemBuilder: (_, index) {
return Card(
child: Padding(
padding: EdgeInsets.all(8),
child: Text("Element at index($index)"),
),
);
},
),
),
],
),
);
},
),
),
),
);
},
);
}
Just change your Column
into a ListView
, like so:
return ListView(
children: <Widget>[
...
]
);
What if I don't want the content of the sheet to be scrolled, but the sheet itself?
If you want the user to be able to swipe up the bottom sheet to fill the screen, I'm afraid this isn't possible in the current implementation of the modular bottom sheet.