showModalBottomSheet does not provide any styling or decorations. I want to create something like the Google Tasks bottomsheet.
-
use the showModalBottomSheet shape property which takes ShapeBorder – Code with Benji Oct 18 '22 at 09:35
17 Answers
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) => ???,
);

- 3,117
- 2
- 10
- 6
-
1+1. For me it was not sufficient to wrap only the button which contained the method for showing the modal bar. But wrapping the Scaffold which contained the screen with such a Theme worked. `@override Widget build(BuildContext context) { return Theme( // We need this theme override so that the corners of the bottom sheet modal can be rounded data: ThemeData(canvasColor: Colors.transparent), child: Scaffold( ....` – Simon Olsen Apr 01 '19 at 11:28
-
1For me I also needed to add `clipBehaviour: Clip.hardEdge` to make to corners round – Fah May 08 '23 at 10:44
showModalBottomSheet(
context:context
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.antiAliasWithSaveLayer,
)

- 129
- 1
- 11

- 1,459
- 1
- 11
- 8
-
3This would be a better answer if you explained how the code you provided answers the question. – pppery Jun 19 '20 at 00:55
-
-
2this should be accepted answer as it doens't require setting canvas color globally. it's more concise – laszlo Apr 14 '21 at 10:01
-
5`Clip.antiAliasWithSaveLayer` makes it so that if the content of the modal sheet is scrollable, the scrollable content will also be clipped to the modal's border radius if anyone was wondering. – テッド Jul 19 '21 at 16:00
-
clipBehavior: Clip.antiAlias should be preferred, since Clip.antiAliasWithSaveLayer is very slow. – linxie Feb 17 '22 at 15:06
-
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.

- 1,351
- 1
- 10
- 7
-
13Changing global `canvasColor` for a bottomSheet round corner is not a good tradeoff. use `Theme` wrapper instead. Also if you widgets inside the bottom sheet is theme depended then use `data: yourTheme().copyWith(canvasColor: Colors.transparent)` just to apply canvas color only to its child. Best option would be the Updated one. – sh0umik Oct 14 '19 at 09:17
-
-
1Doing this will change canvas color for all the app, which means that, for example, the 'Select/Copy/Paste' native tooltip will have a transparent background color instead of the default white. I think this should be the correct answer: https://stackoverflow.com/a/62457068/7691350 – Jose Jet Dec 11 '20 at 12:03
-
1Theme wrapper with canvasColor not worked. So I used `bottomSheetTheme: BottomSheetThemeData(backgroundColor: Colors.transparent)` in MaterialApp theme. – temirbek Aug 17 '21 at 07:40
-
1I think using bottomSheetTheme as @temirbek's answer is the best way in this case. – apieceofcode1801 Apr 22 '22 at 04:18
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.

- 4,218
- 1
- 25
- 35
i have this code and work well for me. please check it and let me know you'r opinion.
showBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
context: context,
builder: (context) => Container(
height: 250,
child: new Container(
decoration: new BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(20.0),
topRight: const Radius.circular(20.0))),
child: new Center(
child: new Text("This is a modal sheet"),
)),
))

- 761
- 9
- 22
You can now simply set the shape
argument.
Example:
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
context: context,
builder: (context) => MyBottomSheet(),
);

- 3,204
- 1
- 20
- 28
one way is by usingshowModalBottomSheet
shape
property,
showModalBottomSheet(
context:context
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0),
),
),
)

- 111
- 1
- 3
Set the shape to RoundedRectangleBorder should work, but sometimes the content overflows making round corners missing, when this happens set clipBehavior to Clip.antiAlias to resolve.
showModalBottomSheet(
isScrollControlled: true,
backgroundColor: colorOnPrimary,
// set this when inner content overflows, making RoundedRectangleBorder not working as expected
clipBehavior: Clip.antiAlias,
// set shape to make top corners rounded
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
context: context,
builder: (context) {
return SingleChildScrollView(
child: Container(),
);
},
)

- 1,849
- 15
- 20
Putting together all the answers before, I could achieve the best result possible (in my opinion) for this.
showModalBottomSheet(
context: context,
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0)),
),
builder: (context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.email),
title: Text('Send email'),
onTap: () {
print('Send email');
},
),
ListTile(
leading: Icon(Icons.phone),
title: Text('Call phone'),
onTap: () {
print('Call phone');
},
),
],
);
});

- 91
- 1
- 3
You can add a RoundedRectangleBorder
widget inside the showModalBottomSheet
:
showModalBottomSheet<void>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0)
),
),
)

- 27,830
- 11
- 80
- 100

- 197
- 1
- 8
showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (ctx) {
return Container(
decoration: BoxDecoration(
color: Colors.green, // or some other color
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0)
)
);
});

- 6,679
- 5
- 27
- 41

- 39
- 1
You can give borderRadius in decoration container also.
showModalBottomSheet(
context: context,
builder: (builder){
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(15.0),
topRight: const Radius.circular(15.0))),
child: Center(
child: Text("This is a modal sheet"),
),
);
}
);

- 73
- 1
- 5
showModalBottomSheet(
context:context
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.hardEdge,
)
It will be much better to use Clip.hardEdge. As it is faster than other clipping modes but slower than [none].

- 380
- 1
- 10
Just answered a related question
You can add corners to your bottomSheet
and expand your bottomSheet
according to content present inside it (not restricted to half size of screen)
check out the answer here

- 9,869
- 6
- 42
- 59
you can now do it with the showModelBottomSheet() widget parameter shape
showModalBottomSheet<void>(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(topLeft:
Radius.circular(24),topRight:Radius.circular(24) ),),
context: context,
builder: (BuildContext context) {}
use the showModalBottomSheet
shape:
property which takes ShapeBorder
as shown below
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
),

- 666
- 9
- 17