Flutter DraggableScrollableSheet doesn't show up by pressing button
If you want to use DraggableScrollableSheet
inside showModalBottomSheet
, you can simply call this function.
void _showSheet() {
showModalBottomSheet(
context: context,
isScrollControlled: true, // set this to true
builder: (_) {
return DraggableScrollableSheet(
expand: false,
builder: (_, controller) {
return Container(
color: Colors.blue[500],
child: ListView.builder(
controller: controller, // set this too
itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
),
);
},
);
},
);
}
If you want to do it with Animation
, here is the solution.
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
AnimationController _controller;
Duration _duration = Duration(milliseconds: 500);
Tween<Offset> _tween = Tween(begin: Offset(0, 1), end: Offset(0, 0));
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: _duration);
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: GestureDetector(
child: FloatingActionButton(
child: AnimatedIcon(icon: AnimatedIcons.menu_close, progress: _controller),
elevation: 5,
backgroundColor: Colors.deepOrange,
foregroundColor: Colors.white,
onPressed: () async {
if (_controller.isDismissed)
_controller.forward();
else if (_controller.isCompleted)
_controller.reverse();
},
),
),
body: SizedBox.expand(
child: Stack(
children: <Widget>[
FlutterLogo(size: 500),
SizedBox.expand(
child: SlideTransition(
position: _tween.animate(_controller),
child: DraggableScrollableSheet(
builder: (BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.blue[800],
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text('Item $index'));
},
),
);
},
),
),
),
],
),
),
);
}
}
If you want to show DraggableScrollableSheet
as modal you can use material showModalBottomSheet
method to wrap it. Your sheet will be shown as modal, and you do not have to include it in the widget tree. Please note that under the hood it's pushed as new Route to Navigator, with all its consequences.
onPressed: (){
showModalBottomSheet(
context: context,
isScrollControlled: true,
isDismissible: true,
expand: false,
backgroundColor: Colors.transparent,
builder: (context) =>
DraggableScrollableSheet(
initialChildSize: 0.64,
minChildSize: 0.2,
maxChildSize: 1,
builder: (context, scrollController) {
return Container(
color: Colors.white,
child: ListView.builder(
controller: scrollController,
itemBuilder: (context, index) {
return ListTile(
title: Text('Item $index'),
);
},
itemCount: 20,
),
);
},
),
);
}