Flutter底部弹出菜单插件bottom_sheet_scaffold的使用
Flutter底部弹出菜单插件 bottom_sheet_scaffold
的使用
bottom_sheet_scaffold
是一个非常简单且可高度定制的底部弹出菜单插件。它允许通过滑动 Scaffold
的主体来控制底部弹出菜单的高度,并提供了丰富的功能,如动画透明度、拖动手势等。
特性
- 简单易用
- 通过滑动
Scaffold
主体来确定底部弹出菜单的高度 - 可拖动的底部弹出菜单主体
- 动画透明度
- 完全可定制
- 使用
BottomSheetBuilder
监听底部弹出菜单的状态 - 不需要设置任何头部即可滑动底部弹出菜单
示例效果
使用方法
将你的 Scaffold
替换为 BottomSheetScaffold
:
import 'package:bottom_sheet_scaffold/bottom_sheet_scaffold.dart';
import 'package:flutter/material.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return BottomSheetScaffold(
draggableBody: true,
dismissOnClick: true,
barrierColor: Colors.black54,
bottomSheet: DraggableBottomSheet(
animationDuration: const Duration(milliseconds: 200),
body: Container(
width: double.infinity,
height: 500,
alignment: Alignment.center,
child: const Text(
"Bottom Sheet",
style: TextStyle(fontSize: 36, color: Colors.black),
),
),
header: Container(
height: 60,
color: Colors.blue,
child: const Center(
child: Text(
"Drag me",
style: TextStyle(color: Colors.white),
),
),
),
),
appBar: AppBar(
title: const Text("My AppBar"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 100),
BottomSheetBuilder(
builder: (status, context) {
return MaterialButton(
color: Colors.blue,
onPressed: () {
if (BottomSheetPanel.isExpanded) {
BottomSheetPanel.close();
} else {
BottomSheetPanel.open();
}
},
child: Icon(!status.isExpanded
? Icons.open_in_browser
: Icons.close_fullscreen),
);
},
),
const Text('Body of scaffold'),
],
),
),
);
}
}
自定义 onWillPop
你可以自定义 onWillPop
来处理返回按钮的行为:
BottomSheetScaffold(
draggableBody: true,
dismissOnClick: true,
onWillPop: (() async {
if (BottomSheetPanel.isOpen) {
BottomSheetPanel.close();
return false;
} else {
return true;
}
}),
barrierColor: Colors.black54,
bottomSheet: DraggableBottomSheet(
animationDuration: const Duration(milliseconds: 200),
body: Container(
width: double.infinity,
height: 500,
alignment: Alignment.center,
child: const Text(
"Bottom Sheet",
style: TextStyle(fontSize: 36, color: Colors.black),
),
),
header: Container(
height: 60,
color: Colors.blue,
child: const Center(
child: Text(
"Drag me",
style: TextStyle(color: Colors.white),
),
),
),
),
appBar: AppBar(
title: const Text("My AppBar"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 100),
BottomSheetBuilder(
builder: (status, context) {
return MaterialButton(
color: Colors.blue,
onPressed: () {
if (BottomSheetPanel.isExpanded) {
BottomSheetPanel.close();
} else {
BottomSheetPanel.open();
}
},
child: Icon(!status.isExpanded
? Icons.open_in_browser
: Icons.close_fullscreen),
);
},
),
const Text('Body of scaffold'),
],
),
),
);
处理 Scaffold
内部的屏障显示
如果你在 BottomSheetScaffold
内部使用 Scaffold
,你应该将 Scaffold
的主体包裹在 BarrierViewer
中,以便在打开底部弹出菜单时显示你定义的屏障颜色:
return BottomSheetScaffold(
bottomSheet: DraggableBottomSheet(
animationDuration: const Duration(milliseconds: 200),
body: Container(
width: double.infinity,
height: 500,
alignment: Alignment.center,
child: const Text(
"Bottom Sheet",
style: TextStyle(fontSize: 36, color: Colors.black),
),
),
header: Container(
height: 60,
color: Colors.blue,
child: const Center(
child: Text(
"Drag me",
style: TextStyle(color: Colors.white),
),
),
),
),
appBar: AppBar(
title: const Text("My AppBar"),
),
body: Scaffold(
body: BarrierViewer(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 100),
BottomSheetBuilder(
builder: (status, context) {
return MaterialButton(
color: Colors.blue,
onPressed: () {
if (BottomSheetPanel.isExpanded) {
BottomSheetPanel.close();
} else {
BottomSheetPanel.open();
}
},
child: Icon(!status.isExpanded
? Icons.open_in_browser
: Icons.close_fullscreen),
);
},
),
const Text('Body of scaffold'),
],
),
),
),
),
);
DraggableBottomSheet
参数
DraggableBottomSheet({
super.key,
this.maxHeight = 500,
this.minHeight = 0,
this.header,
this.animationDuration = const Duration(milliseconds: 200),
this.autoSwipped = true,
this.draggableBody = true,
this.gradientOpacity = true,
this.headerVisibilityOnTap = true,
this.backgroundColor = Colors.white60,
this.onHide,
this.radius = 30,
this.onShow,
required this.body,
})
BottomSheetPanel
方法和属性
- 打开底部弹出菜单:
BottomSheetPanel.open();
- 关闭底部弹出菜单:
BottomSheetPanel.close();
- 更新底部弹出菜单的高度:
BottomSheetPanel.updateHeight(double height);
- 检查底部弹出菜单是否打开:
BottomSheetPanel.isOpen;
- 检查底部弹出菜单是否展开:
BottomSheetPanel.isExpanded;
- 检查底部弹出菜单是否折叠:
BottomSheetPanel.isCollapsed;
DraggableArea
使用
如果在 DraggableBottomSheet
中将 draggableBody
设置为 false
,你需要使用 DraggableArea
小部件来滚动底部弹出菜单:
DraggableBottomSheet(
draggableBody: false,
body: Column(
children: [
DraggableArea(
child: Container(
height: 80,
width: double.infinity,
color: Colors.blue,
alignment: Alignment.center,
child: const Text(
"Drag Me",
style: TextStyle(color: Colors.white),
),
),
),
Container(
height: 500,
color: Colors.red,
child: const Center(
child: Text(
"Bottom Sheet",
style: TextStyle(fontSize: 36, color: Colors.white),
),
),
)
],
),
)
BottomSheetBuilder
使用
如果你想监听底部弹出菜单的状态并根据状态更改页面上的某些内容,可以使用 BottomSheetBuilder
:
BottomSheetBuilder(
builder: (status, context) {
return FloatingActionButton(
onPressed: () {
if (BottomSheetPanel.isExpanded) {
BottomSheetPanel.close();
} else {
BottomSheetPanel.open();
}
},
child: Icon(!status.isExpanded
? Icons.open_in_browser
: Icons.close_fullscreen),
);
},
)
完整示例代码
import 'package:bottom_sheet_scaffold/bottom_sheet_scaffold.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return BottomSheetScaffold(
bottomSheet: DraggableBottomSheet(
animationDuration: const Duration(milliseconds: 200),
body: Container(
width: double.infinity,
height: 500,
alignment: Alignment.center,
child: const Text(
"Bottom Sheet",
style: TextStyle(fontSize: 36, color: Colors.black),
),
),
header: Container(
height: 60,
color: Colors.blue,
child: const Center(
child: Text(
"Drag me",
style: TextStyle(color: Colors.white),
),
),
),
),
appBar: AppBar(
title: const Text("My AppBar"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
const SizedBox(height: 100),
BottomSheetBuilder(
builder: (status, context) {
return MaterialButton(
color: Colors.blue,
onPressed: () {
if (BottomSheetPanel.isExpanded) {
BottomSheetPanel.close();
} else {
BottomSheetPanel.open();
}
},
child: Icon(!status.isExpanded
? Icons.open_in_browser
: Icons.close_fullscreen),
);
},
),
const Text('Body of scaffold'),
],
),
),
);
}
}
希望这个详细的指南能帮助你更好地理解和使用 bottom_sheet_scaffold
插件!
更多关于Flutter底部弹出菜单插件bottom_sheet_scaffold的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter底部弹出菜单插件bottom_sheet_scaffold的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用bottom_sheet_scaffold
插件来创建底部弹出菜单的示例代码。bottom_sheet_scaffold
是一个非官方的Flutter插件,它提供了一个方便的方式来创建带有可滑动底部面板的页面结构。
首先,确保你已经在pubspec.yaml
文件中添加了bottom_sheet_scaffold
依赖:
dependencies:
flutter:
sdk: flutter
bottom_sheet_scaffold: ^1.0.0 # 请检查最新版本号
然后,运行flutter pub get
来安装依赖。
接下来是一个完整的示例代码,展示了如何使用BottomSheetScaffold
来创建一个带有底部弹出菜单的页面:
import 'package:flutter/material.dart';
import 'package:bottom_sheet_scaffold/bottom_sheet_scaffold.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BottomSheetScaffold Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final List<String> menuItems = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
@override
Widget build(BuildContext context) {
return BottomSheetScaffold(
sheet: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListView.builder(
shrinkWrap: true,
itemCount: menuItems.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(menuItems[index]),
onTap: () {
Navigator.of(context).pop(); // 关闭底部菜单
// 可以在这里添加点击菜单项后的处理逻辑
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Selected: ${menuItems[index]}')),
);
},
);
},
),
],
),
),
appBar: AppBar(
title: Text('BottomSheetScaffold Demo'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 打开底部菜单
BottomSheetScaffold.of(context).showSheet();
},
child: Text('Show Bottom Sheet'),
),
),
);
}
}
在这个示例中:
BottomSheetScaffold
被用作根小部件,它提供了一个带有可滑动底部面板的页面结构。sheet
属性定义了底部菜单的内容。这里我们用一个Container
包裹了一个Column
,其中包含了一个ListView.builder
来动态生成菜单项。- 每个菜单项是一个
ListTile
,点击时会关闭底部菜单并显示一个SnackBar。 - 在
body
中,我们放置了一个ElevatedButton
,点击它会调用BottomSheetScaffold.of(context).showSheet()
方法来显示底部菜单。
请注意,由于bottom_sheet_scaffold
是一个第三方插件,其API可能会随着版本的更新而变化。因此,建议查看最新的官方文档和示例代码以确保兼容性。