BottomSheet
BottomSheet 是从底部滑出的面板,常用于操作菜单、筛选器等。
showModalBottomSheet — 模态弹窗
dart
// 获取返回值
final result = await showModalBottomSheet<String>(
context: context,
isScrollControlled: true, // 允许全屏高度
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (context) => SizedBox(
height: 300,
child: Column(
children: [
// 顶部拖拽指示条
Container(
width: 40,
height: 4,
margin: const EdgeInsets.symmetric(vertical: 12),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(2),
),
),
ListTile(
leading: const Icon(Icons.camera_alt),
title: const Text('拍照'),
onTap: () => Navigator.pop(context, 'camera'),
),
ListTile(
leading: const Icon(Icons.photo_library),
title: const Text('从相册选择'),
onTap: () => Navigator.pop(context, 'gallery'),
),
],
),
),
);
if (result == 'camera') {
// 用户选择了拍照
}适配键盘
dart
showModalBottomSheet(
context: context,
isScrollControlled: true, // 必须
builder: (context) => Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom, // 键盘高度
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const TextField(
decoration: InputDecoration(labelText: '输入内容'),
),
Padding(
padding: const EdgeInsets.all(16),
child: SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('确定'),
),
),
),
],
),
),
)showBottomSheet — 持久面板
dart
// 持久底部面板(不会自动关闭,需要手动关闭)
final controller = showBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (context) => const SizedBox(
height: 200,
child: Center(child: Text('这是底部面板')),
),
);
// 关闭
controller.close();DraggableScrollableSheet — 可拖拽面板
dart
showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) => DraggableScrollableSheet(
initialChildSize: 0.5, // 初始高度(屏幕比例)
minChildSize: 0.25, // 最小高度
maxChildSize: 0.9, // 最大高度
expand: false, // 不自动展开到 maxChildSize
builder: (context, scrollController) {
return ListView.builder(
controller: scrollController,
itemCount: 50,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
);
},
),
)