Flutter滑动面板插件sliding_sheet的使用
Flutter滑动面板插件sliding_sheet的使用
sliding_sheet
是一个可以在单个手势内拖动和滚动,并且可以吸附到一组指定高度的小组件。下面是 sliding_sheet
的使用方法和示例代码。
安装
首先,在 pubspec.yaml
文件中添加依赖:
dependencies:
sliding_sheet: ^0.5.2
然后在命令行中安装包:
flutter packages get
如果你喜欢这个包,别忘了给它一个星以支持它的发展:
使用
作为永久(或持久)组件
这种方法可以用来永久显示 SlidingSheet
组件(通常在其他组件之上)。如示例所示:
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
appBar: AppBar(
title: Text('Simple Example'),
),
body: SlidingSheet(
elevation: 8,
cornerRadius: 16,
snapSpec: const SnapSpec(
// 启用吸附功能。默认为true。
snap: true,
// 设置自定义吸附点。
snappings: [0.4, 0.7, 1.0],
// 指定吸附点相对于什么。在这种情况下,吸附点相对于可扩展的高度。
positioning: SnapPositioning.relativeToAvailableSpace,
),
// 背景组件将显示在 SlidingSheet 下方,
// 并且可以应用视差效果。
body: Center(
child: Text('This widget is below the SlidingSheet'),
),
builder: (context, state) {
// 这是吸附面板的内容,如果内容比吸附面板的高度大,则可以滚动。
return Container(
height: 500,
child: Center(
child: Text('This is the content of the sheet'),
),
);
},
),
);
}
结果:
作为 BottomSheetDialog
这种方法可以通过调用 showSlidingBottomSheet
函数并返回一个 SlidingSheetDialog
实例来显示 SlidingSheet
。
void showAsBottomSheet() async {
final result = await showSlidingBottomSheet(
context,
builder: (context) {
return SlidingSheetDialog(
elevation: 8,
cornerRadius: 16,
snapSpec: const SnapSpec(
snap: true,
snappings: [0.4, 0.7, 1.0],
positioning: SnapPositioning.relativeToAvailableSpace,
),
builder: (context, state) {
return Container(
height: 400,
child: Center(
child: Material(
child: InkWell(
onTap: () => Navigator.pop(context, 'This is the result.'),
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(
'This is the content of the sheet',
style: Theme.of(context).textTheme.body1,
),
),
),
),
),
);
},
);
}
);
print(result); // This is the result.
}
结果:
吸附功能
SlidingSheet
可以吸附到多个高度或不吸附任何高度。通过传递 SnapSpec
实例可以自定义吸附行为。
SnapSpec(
snap: true, // 如果为真,SlidingSheet 将吸附到提供的 snappings。
snappings: [0.4, 0.7, 1.0], // 吸附点。
positioning: SnapPositioning.relativeToAvailableSpace, // 吸附点的位置。
onSnap: (state, snap) { // 当 SlidingSheet 吸附到某个高度时调用。
print('Snapped to $snap');
},
)
还可以利用预构建的吸附点来吸附到头部或尾部等特定位置。
SheetController
SheetController
可以手动改变 SlidingSheet
的状态。只需将 SheetController
实例传递给 SlidingSheet
即可。也可以使用静态方法 SheetController.of(context)
获取最近的 SlidingSheet
的 SheetController
。
class SheetController {
void expand(); // 扩展 SlidingSheet 到最大高度。
void collapse(); // 收缩 SlidingSheet 到最小高度。
void snapToExtent(double extent); // 吸附到任意高度。
void scrollTo(double offset); // 滚动到给定偏移量。
void rebuild(); // 重新构建 SlidingSheet 的所有子组件。
void show(); // 显示 SlidingSheet。
void hide(); // 隐藏 SlidingSheet。
}
头部和尾部
头部和尾部是 SlidingSheet
中不会滚动的 UI 元素。头部位于顶部,尾部位于底部。中间的内容部分会滚动。
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey.shade200,
appBar: AppBar(
title: Text('Simple Example'),
),
body: Stack(
children: <Widget>[
SlidingSheet(
elevation: 8,
cornerRadius: 16,
snapSpec: const SnapSpec(
snap: true,
snappings: [112, 400, double.infinity],
positioning: SnapPositioning.pixelOffset,
),
builder: (context, state) {
return Container(
height: 500,
child: Center(
child: Text(
'This is the content of the sheet',
style: Theme.of(context).textTheme.body1,
),
),
);
},
headerBuilder: (context, state) {
return Container(
height: 56,
width: double.infinity,
color: Colors.green,
alignment: Alignment.center,
child: Text(
'This is the header',
style: Theme.of(context).textTheme.body1.copyWith(color: Colors.white),
),
);
},
footerBuilder: (context, state) {
return Container(
height: 56,
width: double.infinity,
color: Colors.yellow,
alignment: Alignment.center,
child: Text(
'This is the footer',
style: Theme.of(context).textTheme.body1.copyWith(color: Colors.black),
),
);
},
),
],
),
);
}
结果:
ListViews 和 Columns
SlidingSheet
的子组件不允许无限(无边界)高度。因此,当使用 ListView
时,请确保设置 shrinkWrap
为 true
并且 physics
为 NeverScrollableScrollPhysics
。同样地,当使用 Column
作为 SlidingSheet
的子组件时,请确保设置 mainAxisSize
为 MainAxisSize.min
。
Material 效应
为了改变交互时的界面,可以在 SlidingSheet
中传递一个回调到 listener
字段,该回调会在滑动或滚动时被调用。你可以根据当前的 SheetState
来重建你的界面。使用 SheetController.rebuild()
可以在使用 bottomSheetDialog
时重新构建面板。
return SheetListenerBuilder(
buildWhen: (oldState, newState) => oldState.isAtTop != newState.isAtTop,
builder: (context, state) {
return AnimatedContainer(
elevation: !state.isAtTop ? elevation : 0.0,
duration: const Duration(milliseconds: 400),
child: child,
);
},
);
更多关于Flutter滑动面板插件sliding_sheet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter滑动面板插件sliding_sheet的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用sliding_sheet
插件来实现滑动面板功能的示例代码。sliding_sheet
是一个流行的Flutter插件,它允许你创建类似于底部面板(Bottom Sheet)的滑动组件,但提供了更多的自定义选项和动画效果。
首先,你需要在你的pubspec.yaml
文件中添加sliding_sheet
依赖:
dependencies:
flutter:
sdk: flutter
sliding_sheet: ^x.y.z # 请替换为最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,我们来看一个完整的示例代码,展示如何使用sliding_sheet
:
import 'package:flutter/material.dart';
import 'package:sliding_sheet/sliding_sheet.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sliding Sheet Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
late SlidingSheetController _controller;
@override
void initState() {
super.initState();
_controller = SlidingSheetController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sliding Sheet Demo'),
),
body: Column(
children: [
Expanded(
child: Center(
child: ElevatedButton(
onPressed: () {
// 打开滑动面板
_controller.expand();
},
child: Text('Open Sheet'),
),
),
),
SlidingSheet(
controller: _controller,
sheet: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
padding: EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('这是一个滑动面板'),
SizedBox(height: 16),
ElevatedButton(
onPressed: () {
// 关闭滑动面板
_controller.collapse();
},
child: Text('关闭'),
),
],
),
),
snapPoints: [100, 300], // 自定义的两个停靠点
peekHeight: 100, // 初始显示高度
initialExpansion: 0.5, // 初始展开比例
),
],
),
);
}
}
代码解释
-
依赖添加:确保在
pubspec.yaml
中添加了sliding_sheet
依赖。 -
控制器初始化:在
_MyHomePageState
中初始化了一个SlidingSheetController
,用于控制滑动面板的展开和收起。 -
按钮触发:在
body
中,有一个按钮用于触发滑动面板的展开。点击按钮时,调用_controller.expand()
方法。 -
滑动面板:
SlidingSheet
组件是滑动面板的主体,设置了controller
、sheet
、snapPoints
、peekHeight
和initialExpansion
等属性。controller
:用于控制滑动面板的控制器。sheet
:滑动面板的内容,这里是一个简单的Container
,包含一些文本和一个关闭按钮。snapPoints
:定义滑动面板可以停靠的高度列表。peekHeight
:滑动面板初始显示的高度。initialExpansion
:滑动面板初始的展开比例(0.0到1.0之间)。
-
关闭按钮:在滑动面板内部,有一个按钮用于关闭面板,点击时调用
_controller.collapse()
方法。
这个示例展示了如何使用sliding_sheet
插件创建一个简单的滑动面板,并包含了基本的展开和收起功能。你可以根据实际需求进一步自定义和扩展。