如何在 Flutter 中创建一个带有圆角的模态 bottomsheet?
How to create a modal bottomsheet with circular corners in Flutter?
showModalBottomSheet 不提供任何样式或装饰。我想创建类似 Google 任务底页的内容。
这是所需的 modalBottomSheet 函数。
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"),
)),
);
}
);
}
此外,这项工作最重要的部分是,在 MaterialApp 中将 canvasColor 设置为透明,如下所示。
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Tasks',
theme: new ThemeData(
primarySwatch: Colors.teal,
canvasColor: Colors.transparent,
),
home: new TasksHomePage(),
);
}
我已经测试了代码并且它工作正常,因为我也在制作 Google Tasks 应用程序的克隆,它将在我的 github.
中开源
更新于 2019-08-05
您现在可以使用默认的 showModalBottomSheet
方法完成此操作,该方法现在支持添加 ShapeBorder
和 backgroundColor
!
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
backgroundColor: Colors.white,
...
);
--
我决定查看 showModalBottomSheet
的实现并找出问题所在,而不是像其他答案所建议的那样覆盖应用程序的整个主题(这导致我的应用程序的各个部分出现问题)我。事实证明,所需要的只是将模态的主要代码包装在包含 canvasColor: Colors.transparent
技巧的 Theme
小部件中。我还让自定义半径和模态本身的颜色变得更容易。
您可以使用包含相同代码的 package on pub or a gist。不要忘记导入正确的 package/file.
showRoundedModalBottomSheet(
context: context,
radius: 20.0, // This is the default
color: Colors.white, // Also default
builder: (context) => ???,
);
您现在可以简单地设置 shape
参数。
示例:
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
context: context,
builder: (context) => MyBottomSheet(),
);
将之前的所有答案放在一起,我可以得到最好的结果(在我看来)。
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');
},
),
],
);
});
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)
)
);
});
刚刚回答了一个相关问题
您可以为您的bottomSheet
添加角点,并根据其中的内容扩展您的bottomSheet
(不限于屏幕的一半大小)
查看答案here
我认为制作圆角模态框的最佳方法是使用带有垂直 BorderRadius
的 RoundedRectangleBorder
,仅设置其 top
属性:
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
),
builder: (BuildContext context) {
// return your layout
});
对左上角和右上角使用单独的半径有点冗长且容易出错。
我有这段代码,对我来说效果很好。请检查并告诉我你的意见。
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"),
)),
))
showModalBottomSheet(
context:context
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.antiAliasWithSaveLayer,
)
您可以在 showModalBottomSheet
:
中添加一个 RoundedRectangleBorder
小部件
showModalBottomSheet<void>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0)
),
),
)
也可以在装饰容器中赋予borderRadius
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"),
),
);
}
);
对于持久底部 sheet,在 material 应用小部件的主题中添加以下代码 属性
ThemeData(
bottomSheetTheme: BottomSheetThemeData(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
showModalBottomSheet(
context:context
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.hardEdge,
)
使用Clip.hardEdge会好很多。因为它比其他剪辑模式快但比 [none].
慢
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(),
);
},
)
一种方法是使用showModalBottomSheet
shape
属性,
showModalBottomSheet(
context:context
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0),
),
),
)
showModalBottomSheet 不提供任何样式或装饰。我想创建类似 Google 任务底页的内容。
这是所需的 modalBottomSheet 函数。
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"),
)),
);
}
);
}
此外,这项工作最重要的部分是,在 MaterialApp 中将 canvasColor 设置为透明,如下所示。
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Tasks',
theme: new ThemeData(
primarySwatch: Colors.teal,
canvasColor: Colors.transparent,
),
home: new TasksHomePage(),
);
}
我已经测试了代码并且它工作正常,因为我也在制作 Google Tasks 应用程序的克隆,它将在我的 github.
中开源更新于 2019-08-05
您现在可以使用默认的 showModalBottomSheet
方法完成此操作,该方法现在支持添加 ShapeBorder
和 backgroundColor
!
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
backgroundColor: Colors.white,
...
);
--
我决定查看 showModalBottomSheet
的实现并找出问题所在,而不是像其他答案所建议的那样覆盖应用程序的整个主题(这导致我的应用程序的各个部分出现问题)我。事实证明,所需要的只是将模态的主要代码包装在包含 canvasColor: Colors.transparent
技巧的 Theme
小部件中。我还让自定义半径和模态本身的颜色变得更容易。
您可以使用包含相同代码的 package on pub or a gist。不要忘记导入正确的 package/file.
showRoundedModalBottomSheet(
context: context,
radius: 20.0, // This is the default
color: Colors.white, // Also default
builder: (context) => ???,
);
您现在可以简单地设置 shape
参数。
示例:
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
context: context,
builder: (context) => MyBottomSheet(),
);
将之前的所有答案放在一起,我可以得到最好的结果(在我看来)。
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');
},
),
],
);
});
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)
)
);
});
刚刚回答了一个相关问题
您可以为您的bottomSheet
添加角点,并根据其中的内容扩展您的bottomSheet
(不限于屏幕的一半大小)
查看答案here
我认为制作圆角模态框的最佳方法是使用带有垂直 BorderRadius
的 RoundedRectangleBorder
,仅设置其 top
属性:
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
),
builder: (BuildContext context) {
// return your layout
});
对左上角和右上角使用单独的半径有点冗长且容易出错。
我有这段代码,对我来说效果很好。请检查并告诉我你的意见。
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"),
)),
))
showModalBottomSheet(
context:context
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.antiAliasWithSaveLayer,
)
您可以在 showModalBottomSheet
:
RoundedRectangleBorder
小部件
showModalBottomSheet<void>(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0)
),
),
)
也可以在装饰容器中赋予borderRadius
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"),
),
);
}
);
对于持久底部 sheet,在 material 应用小部件的主题中添加以下代码 属性
ThemeData(
bottomSheetTheme: BottomSheetThemeData(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
),
),
showModalBottomSheet(
context:context
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.hardEdge,
)
使用Clip.hardEdge会好很多。因为它比其他剪辑模式快但比 [none].
慢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(),
);
},
)
一种方法是使用showModalBottomSheet
shape
属性,
showModalBottomSheet(
context:context
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0),
),
),
)