一、showModalBottomSheet(模态底部弹出框)
showModalBottomSheet 用于显示一个模态底部弹出框。
属性解析:
Future<T?> showModalBottomSheet<T>({
required BuildContext context, // 表示底部弹出框所处的上下文,通常来自当前 widget。
required WidgetBuilder builder, // 用于构建弹出框内容的函数。它传递一个 BuildContext 并返回一个 Widget,这通常是弹出框的主体。
Color? backgroundColor, // 底部弹出框的背景颜色。
String? barrierLabel, // 屏障的语义标签,用于无障碍功能。
double? elevation, // 底部弹出框的阴影高度。
ShapeBorder? shape, // 底部弹出框的形状,例如圆角矩形。
Clip? clipBehavior, // 如何裁剪底部弹出框的内容。
BoxConstraints? constraints, // 底部弹出框的布局约束。
Color? barrierColor, // 弹出框背景障碍物(屏幕其余部分)的颜色。
bool isScrollControlled = false, // 是否允许弹出框内部滚动。默认为 false。
double scrollControlDisabledMaxHeightRatio = _defaultScrollControlDisabledMaxHeightRatio, // 在禁用滚动控制时,最大高度的比例。
bool useRootNavigator = false, // 是否使用根导航器来推送弹出框。默认为 false。
bool isDismissible = true, // 指示用户点击屏幕背景(弹出框外部)时是否关闭弹出框。默认为 true。
bool enableDrag = true, // 是否允许通过拖动来关闭弹出框。默认为 true。
bool? showDragHandle, // 是否显示拖动手柄。
bool useSafeArea = false, // 是否考虑安全区域(如异形屏幕的凹槽、状态栏等)。默认为 false。
RouteSettings? routeSettings, // 传递给弹出框路由的配置信息,如名称和参数。
AnimationController? transitionAnimationController, // 自定义弹出框的动画控制器。
Offset? anchorPoint, // 指定弹出框弹出的锚点位置。
})
示例:
// 主页面
class MyHomeBody extends StatelessWidget {
const MyHomeBody({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
// 垂直布局
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 平均分布各个 Widget
crossAxisAlignment: CrossAxisAlignment.stretch, // 填充整个交叉轴
mainAxisSize: MainAxisSize.max,
children: <Widget>[
ElevatedButton(
onPressed: () {
_showMyModalBottomSheet(context);
},
style: ElevatedButton.styleFrom(
minimumSize: const Size(160, 80),
),
child: Text("AlertDialog(提示对话框)"),
),
],
);
}
}
// showModalBottomSheet(模态底部弹出框)
Future<void> _showMyModalBottomSheet(BuildContext context) async {
return showModalBottomSheet<void>(
context: context,
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(25.0)),
),
isScrollControlled: true,
builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('This is a modal bottom sheet.'),
SizedBox(height: 20),
ElevatedButton(
child: Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
),
);
},
);
}
效果图如下所示:
二、Persistent Bottom Sheet(Scaffold的showBottomSheet方法)
这个方法显示一个持久的底部弹出层,不会在点击外部区域时自动关闭。
属性解析:
PersistentBottomSheetController showBottomSheet(
WidgetBuilder builder, { // 用于构建弹出框内容的函数。它传递一个 BuildContext 并返回一个 Widget,这通常是弹出框的主体。
Color? backgroundColor, // 底部弹出框的背景颜色
double? elevation, // 底部弹出框的阴影高度。
ShapeBorder? shape, // 底部弹出框的形状,例如圆角矩形。
Clip? clipBehavior, // 如何裁剪底部弹出框的内容。
BoxConstraints? constraints, // 底部弹出框的布局约束。
bool? enableDrag, // 是否允许通过拖动来关闭弹出框。
AnimationController? transitionAnimationController, // 自定义弹出框的动画控制器。
})
示例:
// 主页面
class MyHomeBody extends StatelessWidget {
const MyHomeBody({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
// 垂直布局
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 平均分布各个 Widget
crossAxisAlignment: CrossAxisAlignment.stretch, // 填充整个交叉轴
mainAxisSize: MainAxisSize.max,
children: <Widget>[
ElevatedButton(
onPressed: () {
Scaffold.of(context).showBottomSheet(
(BuildContext context) {
return Container(
color: Colors.white,
height: 200,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.photo),
title: Text('照片'),
onTap: () {},
),
ListTile(
leading: Icon(Icons.music_note),
title: Text('音乐'),
onTap: () {},
),
ListTile(
leading: Icon(Icons.videocam),
title: Text('视频'),
onTap: () {},
),
],
),
),
);
},
);
},
child: Text('显示持久底部弹出层'),
),
],
);
}
}
效果图如下所示:
三、PopupMenuButton(弹出菜单)
PopupMenuButton 是一个 Flutter widget,用于显示弹出菜单,当用户点击按钮时,会显示一组选项。
属性解析:
const PopupMenuButton({
super.key, // 控件的键值,用于标识控件。
required this.itemBuilder, // 构建菜单项的函数,返回一个 List<PopupMenuEntry>。
this.initialValue, // 菜单打开时选中的初始值。
this.onOpened, // 菜单打开时的回调函数。
this.onSelected, // 菜单选项被选中后的回调函数。
this.onCanceled, // 菜单被取消时的回调函数。
this.tooltip, // 按钮的提示文本。
this.elevation, // 菜单的阴影高度。
this.shadowColor, // 菜单阴影的颜色。
this.surfaceTintColor, // 表面色调的颜色(用于材料设计3)。
this.padding = const EdgeInsets.all(8.0), // 按钮的内边距。默认值为 EdgeInsets.all(8.0)。
this.child, // 按钮的子小部件。如果不提供,将使用 icon。
this.splashRadius, // 按钮点击时水波纹的半径。
this.icon, // 按钮的图标。如果不提供,将使用 child。
this.iconSize, // 图标的大小。
this.offset = Offset.zero, // 菜单相对于按钮的偏移量。默认值为 Offset.zero。
this.enabled = true, // 按钮是否可用。默认为 true。
this.shape, // 菜单的外形。
this.color, // 菜单的背景颜色。
this.iconColor, // 图标的颜色。
this.enableFeedback, // 是否启用声音和触觉反馈。
this.constraints, // 按钮的约束条件。
this.position, // 菜单的位置。
this.clipBehavior = Clip.none, // 菜单的剪裁行为。
this.useRootNavigator = false, // 是否使用根导航器来推送菜单。默认为 false。
this.popUpAnimationStyle, // 弹出菜单的动画样式。
})
示例:
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Dialog Page"),
),
body: PopupMenuButtonDemo(),
),
);
}
}
class PopupMenuButtonDemo extends StatelessWidget {
const PopupMenuButtonDemo({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: PopupMenuButton<String>(
onSelected: (String result) {
print('Selected: $result');
},
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuItem<String>(
value: 'Option 1',
child: Text('Option 1'),
),
const PopupMenuItem<String>(
value: 'Option 2',
child: Text('Option 2'),
),
const PopupMenuItem<String>(
value: 'Option 3',
child: Text('Option 3'),
),
],
icon: Icon(Icons.more_vert),
offset: Offset(0, 50), // 设置菜单相对于按钮的偏移量
elevation: 8.0,
onCanceled: () {
print('Menu canceled');
},
tooltip: 'Show options',
),
);
}
}
效果图如下所示:
四、ExpansionPanelList(展开和折叠的面板)
ExpansionPanelList 是一个 Flutter widget,用于显示一组可以展开和折叠的面板。每个面板在展开状态下可以显示更多内容,非常适合展示分层或分段的信息。
属性解析:
const ExpansionPanelList({
super.key, // 控件的键值,用于标识控件。
this.children = const <ExpansionPanel>[], // 要显示的扩展面板列表。每个 ExpansionPanel 可以包含标题和内容。
this.expansionCallback, // 当某个面板展开或折叠时触发的回调函数。接受两个参数:面板索引和当前的展开状态。
this.animationDuration = kThemeAnimationDuration, // 展开和折叠动画的持续时间。
this.expandedHeaderPadding = _kPanelHeaderExpandedDefaultPadding, // 已展开面板标题的内边距。
this.dividerColor, // 面板之间分隔线的颜色。
this.elevation = 2, // 面板的阴影高度。
this.expandIconColor, // 扩展图标的颜色。
this.materialGapSize = 16.0, // 面板之间的间隙大小。
})
示例:
expansionPanelList.dart
// expansionPanelList.dart
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
class ExpansionPanelListDemo extends StatefulWidget {
const ExpansionPanelListDemo({Key? key}) : super(key: key);
@override
_ExpansionPanelListDemoState createState() => _ExpansionPanelListDemoState();
}
class _ExpansionPanelListDemoState extends State<ExpansionPanelListDemo> {
final List<Item> _data = generateItems(3);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(10.0),
child: ExpansionPanelList(
animationDuration: Duration(milliseconds: 500),
expansionCallback: (int index, bool isExpanded) {
setState(() {
_data[index].isExpanded = !isExpanded;
});
},
children: _data.map<ExpansionPanel>((Item item) {
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
title: Text(item.headerValue),
);
},
body: ListTile(
title: Text(item.expandedValue),
subtitle: Text('To delete this panel, tap the trash icon'),
trailing: Icon(Icons.delete),
onTap: () {
setState(() {
_data.removeWhere((currentItem) => item == currentItem);
});
},
),
isExpanded: item.isExpanded,
);
}).toList(),
),
),
);
}
}
class Item {
Item({
required this.expandedValue,
required this.headerValue,
this.isExpanded = false,
});
String expandedValue;
String headerValue;
bool isExpanded;
}
List<Item> generateItems(int numberOfItems) {
return List<Item>.generate(numberOfItems, (int index) {
return Item(
headerValue: 'Panel $index',
expandedValue: 'This is item number $index',
);
});
}
main.dart
// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';
import 'widgets/expansionPanelList.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Dialog Page"),
),
body: ExpansionPanelListDemo(),
),
);
}
}
效果图如下所示:
五、SnackBar
SnackBar 是一个 Flutter 小部件,用于显示短暂的消息,通常在屏幕底部。
属性解析:
const SnackBar({
super.key, // 用于标识小部件的唯一键。
required this.content, // SnackBar 的主要内容,通常是一个 Text 小部件。
this.backgroundColor, // 背景颜色。
this.elevation, // 阴影高度。
this.margin, // 外边距。
this.padding, // 内边距。
this.width, // 宽度。
this.shape, // 形状,例如圆角矩形。
this.hitTestBehavior, // 命中测试行为,决定如何处理点击事件。
this.behavior, // SnackBar 的行为,可能是固定的或浮动的。
this.action, // SnackBar 上的操作按钮。
this.actionOverflowThreshold, // 操作按钮溢出的阈值。
this.showCloseIcon, // 是否显示关闭图标。
this.closeIconColor, // 关闭图标的颜色。
this.duration = _snackBarDisplayDuration, // 显示时长。默认为 _snackBarDisplayDuration。
this.animation, // 自定义动画。
this.onVisible, // SnackBar 可见时调用的回调函数。
this.dismissDirection, // SnackBar 可以被滑动以消失的方向。
this.clipBehavior = Clip.hardEdge, // 裁剪行为,默认值为 Clip.hardEdge。
})
示例:
class SnackBarDemo extends StatelessWidget {
const SnackBarDemo({Key? key}) : super(key: key);
void _showSnackBar(BuildContext context) {
final snackBar = SnackBar(
content: Text('This is a Snackbar!'),
action: SnackBarAction(
label: 'Undo',
onPressed: () {
// Some code to undo the change.
},
),
backgroundColor: Colors.blue,
elevation: 10.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
duration: Duration(seconds: 3),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
效果图如下所示:
六、自定义BottomSheet
如果你需要一个完全自定义的 BottomSheet 而不是使用 showModalBottomSheet 或 Scaffold.showBottomSheet,你可以直接创建一个自定义的 BottomSheet 组件:
// 主页面
class MyHomeBody extends StatelessWidget {
const MyHomeBody({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
// 垂直布局
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 平均分布各个 Widget
crossAxisAlignment: CrossAxisAlignment.stretch, // 填充整个交叉轴
mainAxisSize: MainAxisSize.max,
children: <Widget>[
ElevatedButton(
onPressed: () {
showCustomBottomSheet(context);
},
style: ElevatedButton.styleFrom(
minimumSize: const Size(160, 80),
),
child: Text("AlertDialog(提示对话框)"),
),
],
);
}
}
void showCustomBottomSheet(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return Container(
height: 300,
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'自定义底部弹出层',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
SizedBox(height: 16),
Text('你可以在这里放置任何内容。'),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('关闭'),
),
],
),
);
},
);
}
效果图如下所示:
参考:
Flutter 初识:对话框和弹出层_flutter 正在发布 弹出层-CSDN博客
标签:const,key,Text,BuildContext,弹出,context,组件,Flutter From: https://www.cnblogs.com/linuxAndMcu/p/18458662