Flutter BottomSheet 改变宽度
Flutter BottomSheet change width
我希望底部 sheet 看起来像 one in Angular Material。
sheet 而是扩展到最大宽度。问题是我无法配置底部的宽度sheet。
目前看起来像这样
我的代码如下所示:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: ...,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
tooltip: 'Add File',
onPressed: () => showModalBottomSheet(
context: context,
builder: (context) => AddFileBottomSheet(),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
// backgroundColor: Colors.transparent,
isScrollControlled: true,
),
),
),
);
}
}
class AddFileBottomSheet extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
alignment: Alignment.center,
child: Text(
'Create New File',
style: Theme.of(context).textTheme.headline5,
),
),
GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
children: [
_gridTile(
context: context,
icon: Icon(Icons.file_upload),
text: 'Upload File',
callback: () => print('lel'),
),
_gridTile(
context: context,
icon: Icon(Icons.create),
text: 'Create Text File',
callback: () => print('lel'),
),
],
),
],
);
}
Widget _gridTile({
@required BuildContext context,
@required Icon icon,
@required String text,
@required void callback(),
}) {
return InkWell(
onTap: () => callback(),
child: Container(
padding: EdgeInsets.all(15),
alignment: Alignment.center,
height: double.infinity,
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
icon,
Text(text, style: Theme.of(context).textTheme.subtitle2),
],
),
),
);
}
}
我知道我可以在使它的某些部分透明时假装它具有较小的宽度,但我有圆边并且它们不会被保留。
解决方法 #1
我设法通过将 canvasColor
更改为透明并使小部件中的边框变圆来做到这一点:
这样,但是当用户单击假透明区域时,我需要执行额外的逻辑来关闭它。
首先以某种方式将 canvasColor
添加到上下文中:
...
floatingActionButton: Theme(
data: Theme.of(context).copyWith(canvasColor: Colors.transparent),
child: Builder(
builder: (context) => FloatingActionButton(
child: Icon(Icons.add),
tooltip: 'Add File',
onPressed: () => showModalBottomSheet(
context: context,
builder: (context) => AddFileBottomSheet(),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(10),
// topRight: Radius.circular(10),
// ),
// ),
// backgroundColor: Colors.transparent,
isScrollControlled: true,
),
),
),
),
...
然后伪造宽度
return Container(
padding: EdgeInsets.symmetric(horizontal: 300),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
// backgroundColor: Colors.transparent,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
alignment: Alignment.center,
child: Text(
'Create New File',
style: Theme.of(context).textTheme.headline5,
),
),
GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
children: [
_gridTile(
context: context,
icon: Icon(Icons.file_upload),
text: 'Upload File',
callback: () => print('lel'),
),
_gridTile(
context: context,
icon: Icon(Icons.create),
text: 'Create Text File',
callback: () => print('lel'),
),
],
),
],
),
),
);
我想知道是否有解决此问题的标准方法,我需要您的帮助。我尝试制作一个 DartPad 示例,但它给了我 Script error
.
我的想法是尝试通过类似这样的方式使其对移动设备友好:
final isMobile = MediaQuery.of(context).size.width < 700;
return Container(
padding: EdgeInsets.symmetric(horizontal: isMobile ? 0: 300),
child: ...
)
这将使它在移动时全角显示,在桌面上显示一些填充。
您可以使用 Align
小部件包裹您的小部件并将对齐方式设置为底部居中,然后如果您想要最大宽度,您可以设置框约束
Align(
alignment: Alignment.bottomCenter,
child: ConstrainedBox(
constraints: BoxConstraints(...),
child: ...
),
)
更新
Flutter 为 showModalBottomSheet 添加了约束,它在 master、dev 和 beta 上可用:)
更新
: Flutter 现在在 showModalBottomSheet
中支持约束 属性
showModalBottomSheet(
context: context,
constraints: BoxConstraints(
maxWidth: Responsive.isMobile(context) ? Get.width : 600,
),
builder: ...
),
我希望底部 sheet 看起来像 one in Angular Material。
我的代码如下所示:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: ...,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
tooltip: 'Add File',
onPressed: () => showModalBottomSheet(
context: context,
builder: (context) => AddFileBottomSheet(),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
// backgroundColor: Colors.transparent,
isScrollControlled: true,
),
),
),
);
}
}
class AddFileBottomSheet extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
alignment: Alignment.center,
child: Text(
'Create New File',
style: Theme.of(context).textTheme.headline5,
),
),
GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
children: [
_gridTile(
context: context,
icon: Icon(Icons.file_upload),
text: 'Upload File',
callback: () => print('lel'),
),
_gridTile(
context: context,
icon: Icon(Icons.create),
text: 'Create Text File',
callback: () => print('lel'),
),
],
),
],
);
}
Widget _gridTile({
@required BuildContext context,
@required Icon icon,
@required String text,
@required void callback(),
}) {
return InkWell(
onTap: () => callback(),
child: Container(
padding: EdgeInsets.all(15),
alignment: Alignment.center,
height: double.infinity,
width: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
icon,
Text(text, style: Theme.of(context).textTheme.subtitle2),
],
),
),
);
}
}
我知道我可以在使它的某些部分透明时假装它具有较小的宽度,但我有圆边并且它们不会被保留。
解决方法 #1
我设法通过将 canvasColor
更改为透明并使小部件中的边框变圆来做到这一点:
首先以某种方式将 canvasColor
添加到上下文中:
...
floatingActionButton: Theme(
data: Theme.of(context).copyWith(canvasColor: Colors.transparent),
child: Builder(
builder: (context) => FloatingActionButton(
child: Icon(Icons.add),
tooltip: 'Add File',
onPressed: () => showModalBottomSheet(
context: context,
builder: (context) => AddFileBottomSheet(),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.only(
// topLeft: Radius.circular(10),
// topRight: Radius.circular(10),
// ),
// ),
// backgroundColor: Colors.transparent,
isScrollControlled: true,
),
),
),
),
...
然后伪造宽度
return Container(
padding: EdgeInsets.symmetric(horizontal: 300),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10),
),
),
// backgroundColor: Colors.transparent,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 5),
alignment: Alignment.center,
child: Text(
'Create New File',
style: Theme.of(context).textTheme.headline5,
),
),
GridView.count(
shrinkWrap: true,
crossAxisCount: 3,
children: [
_gridTile(
context: context,
icon: Icon(Icons.file_upload),
text: 'Upload File',
callback: () => print('lel'),
),
_gridTile(
context: context,
icon: Icon(Icons.create),
text: 'Create Text File',
callback: () => print('lel'),
),
],
),
],
),
),
);
我想知道是否有解决此问题的标准方法,我需要您的帮助。我尝试制作一个 DartPad 示例,但它给了我 Script error
.
我的想法是尝试通过类似这样的方式使其对移动设备友好:
final isMobile = MediaQuery.of(context).size.width < 700;
return Container(
padding: EdgeInsets.symmetric(horizontal: isMobile ? 0: 300),
child: ...
)
这将使它在移动时全角显示,在桌面上显示一些填充。
您可以使用 Align
小部件包裹您的小部件并将对齐方式设置为底部居中,然后如果您想要最大宽度,您可以设置框约束
Align(
alignment: Alignment.bottomCenter,
child: ConstrainedBox(
constraints: BoxConstraints(...),
child: ...
),
)
更新
Flutter 为 showModalBottomSheet 添加了约束,它在 master、dev 和 beta 上可用:)
更新 : Flutter 现在在 showModalBottomSheet
中支持约束 属性showModalBottomSheet(
context: context,
constraints: BoxConstraints(
maxWidth: Responsive.isMobile(context) ? Get.width : 600,
),
builder: ...
),