How to create a modal bottomsheet with circular corners in Flutter?

showModalBottomSheet does not provide any styling or decorations. I want to create something like the Google Tasks bottomsheet.

google tasks bottomsheet


Solution 1:

UPDATED ON 2019-08-05

You can now do it using the default showModalBottomSheet method that now supports adding a ShapeBorder and also backgroundColor!

showModalBottomSheet(
  shape: RoundedRectangleBorder(
     borderRadius: BorderRadius.circular(10.0),
  ),
  backgroundColor: Colors.white,
  ...
);

--

Instead of overriding the entire theme of the app (which caused problems in various parts of my app) as suggested by other answers, I decided to take a look at the implementation for showModalBottomSheet and find the problem myself. Turns out that all that was needed was wrapping the main code for the modal in a Theme widget that contains the canvasColor: Colors.transparent trick. I also made it easier to customize the radius and also the color of the modal itself.

You can use either the package on pub or a gist containing the same code. Don't forget to import the proper package/file.

showRoundedModalBottomSheet(
    context: context,
    radius: 20.0,  // This is the default
    color: Colors.white,  // Also default
    builder: (context) => ???,
);

Solution 2:

This is the modalBottomSheet function needed.

    void _modalBottomSheetMenu(){
        showModalBottomSheet(
            context: context,
            builder: (builder){
              return new Container(
                height: 350.0,
                color: Colors.transparent, //could change this to Color(0xFF737373), 
                           //so you don't have to change MaterialApp canvasColor
                child: new Container(
                    decoration: new BoxDecoration(
                        color: Colors.white,
                        borderRadius: new BorderRadius.only(
                            topLeft: const Radius.circular(10.0),
                            topRight: const Radius.circular(10.0))),
                    child: new Center(
                      child: new Text("This is a modal sheet"),
                    )),
              );
            }
        );
      }

Also the most important part of this working properly is, in MaterialApp set canvasColor to transparent like the one shown below.

return new MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Tasks',
      theme: new ThemeData(
        primarySwatch: Colors.teal,
        canvasColor: Colors.transparent,
      ),
      home: new TasksHomePage(),
    );
  }

I have tested the code and it works fine as I was also making a clone of the Google Tasks app which will be opensourced in my github.

Solution 3:

showModalBottomSheet(
context:context
shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(
          top: Radius.circular(20),
        ),
      ),
      clipBehavior: Clip.antiAliasWithSaveLayer,
)

Solution 4:

I think the best way to do a rounded-corner modal is to use a RoundedRectangleBorder with a vertical BorderRadius, setting only its top property:

showModalBottomSheet(
        context: context,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
        ),
        builder: (BuildContext context) {
          // return your layout
        });

Using separate radii for top left and top right is a bit more verbose and error-prone.