“Revamped” Flutter Bottom Sheet

Sumeet Rukeja
Flutter Community
Published in
3 min readJul 29, 2019

It’s hard to believe if anyone has developed a general-purpose app, an e-commerce app for instance, and haven’t used a bottom sheet(action sheet, in case of iOS).

It is a very important component when it comes to getting inputs from users in various scenarios. Whether it’s about media-pick options or country selection, bottom sheets provide a UX-friendly approach.

Flutter too has a built-in component for using bottom sheets. But, unfortunately, there are glitches to deal with while using it.

  • setState() has no effect on the StatefulWidget used for bottom sheet
  • Sheets dismiss after clicking their bodies

to name a few.

This is what inspired me to twist the default code. And, while we’re at it, why not customize and make it appear from the top too?

Before getting our hands dirty with the code, let’s have a look at what we are getting ourselves into.

So, in order to have complete control over it, I decided to build a screen with a StatefulWidget and make it behave like a bottom sheet. Basically, a bottom sheet has 3 features:

  • A translucent background
  • Pull-up and push-down animations
  • Gesture control

This is the build method of the StatefulWidget that makes it look and behave like a bottom sheet.

Let’s divide it into parts to understand how it overcomes most of the bottom sheet’s limitations and how it proves to be a bottom sheet on elixir.

Managing background

Scaffold(
backgroundColor: widget.backgroundColor
);

We can provide any color to Scaffold `s background and it will get converted into its translucent version. (Scaffold does it by itself)

Adding animations

_animation = Tween<double>(begin: _isDirectionTop() ? -1 : 1, end: 0).animate(_animationController);

I used basic Tween animation controls to transform the body in an up-down direction. Here, I have used -1 to 0 in case of popping the bottom sheet in top.

Matrix4.translationValues animates the height of the body based on animation value.

GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {},
child: widget.child)

This code, wrapping the body, is used to deal with the issue that dismisses the sheet even when tapping on its body.

Handling gestures

Being a beginner in Flutter, especially in animations, this was challenging for me. I dived into flutter’s default bottom sheet code and tweaked it a little in order to handle top-popup scenario as well.

These 2 methods are where the magic of gesture resides. These are used to manage fling animations and taps outside sheet’s body. I’ve used these in a GestureDetector which wraps the Scaffold.

GestureDetector(
onVerticalDragUpdate: _handleDragUpdate,
onVerticalDragEnd: _handleDragEnd,
child: Scaffold(...)
);

We’re almost done with the customization except for one thing: Android’s back press event. When the user taps the device’s back key, we need to reverse the animation of the sheet.

WillPopScope(
onWillPop: onBackPressed,
child:...
);

This is handled using WillPopScope.

Future<bool> onBackPressed() {
_animationController.reverse();
return Future<bool>.value(false);
}

And we’re done. A big advantage of using this modified sheet is to have great room for more customization. Feel free to check out my GitHub repository to explore the demo I prepared.

Happy Flutter-ing!

--

--

Sumeet Rukeja
Flutter Community

Technology enthusiast, a F.R.I.E.N.D.S fan & a gamer