目录使用源码使用 通过监听滚动事件实现DraGopenDrawer 组件,可以给滚动组件添加一个下拉抽屉。其使用方式如下: DragOpenDrawer( openDuratio
通过监听滚动事件实现DraGopenDrawer 组件,可以给滚动组件添加一个下拉抽屉。其使用方式如下:
DragOpenDrawer(
openDuration: Duration(microseconds: 900),
closeDuration: Duration(milliseconds: 300),
onOpen: (){
print("onOpen");
},
child: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: 40,
itemBuilder: (context,index){
return ListTile(title: Text("$index"),);
}),
),
]
),
backgroundBuilder: (context){
return Container(child: FlutterLogo(style: FlutterLogoStyle.stacked,),color: Colors.blue[200],);
},
),
组件参数说明
运行效果
import 'package:flutter/material.dart';
enum _DragOpenDrawerMode{
// 正在拖动
dragging,
// 抽同打开事件已经触发
done,
// 抽屉处于关闭状态
canceled,
// 抽屉已经打开了
opened,
}
class DragOpenDrawer extends StatefulWidget {
const DragOpenDrawer({
required this.child,
required this.backgroundBuilder,
this.onOpen,
this.openDuration = const Duration(seconds: 1),
this.closeDuration = const Duration(seconds: 1),
Key? key}) : super(key: key);
final Widget Function(BuildContext context) backgroundBuilder;
final Widget child;
/// 抽屉打开时的回调函数
final void Function()? onOpen;
final Duration openDuration;
final Duration closeDuration;
@override
_DragOpenDrawerState createState() => _DragOpenDrawerState();
}
class _DragOpenDrawerState extends State<DragOpenDrawer> with SingleTickerProviderStateMixin {
late AnimationController _controller;
late double _maxHeight;
double _dragOffset = .0;
bool _openTriggered = false;
_DragOpenDrawerMode _dragOpenDrawerMode = _DragOpenDrawerMode.canceled;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
}
@override
void dispose() {
_changeDragOpenDrawerMode(_DragOpenDrawerMode.canceled);
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
_maxHeight = constraints.maxHeight;
return WillPopScope(
onWillPop: () async{
if(_dragOpenDrawerMode == _DragOpenDrawerMode.opened){
_changeDragOpenDrawerMode(_DragOpenDrawerMode.canceled);
return false;
}
return true;
},
child: Stack(
alignment: Alignment.topCenter,
children: [
SizedBox(
width: double.infinity,
height: double.infinity,
child: ScaleTransition(
alignment: Alignment.topCenter,
scale: _controller,
child: widget.backgroundBuilder(context)),
),
AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget? child) {
return Positioned(
top: Tween(begin: .0, end: _maxHeight).evaluate(_controller),
height: _maxHeight,
width: constraints.maxWidth,
child: NotificationListener(
onNotification: (notification){
if(notification is OverscrollNotification){
if(notification.overscroll >= 0){
return true;
}else{
_dragOffset -= notification.overscroll;
_changeDragOpenDrawerMode(_DragOpenDrawerMode.dragging);
if(_dragOffset >_maxHeight/4){
_changeDragOpenDrawerMode(_DragOpenDrawerMode.done);
}
}
}else if(notification is ScrollEndNotification && _dragOpenDrawerMode != _DragOpenDrawerMode.done){
_controller
..duration = widget.closeDuration
..reverse().then((value) => _dragOffset = .0);
}else if(notification is ScrollEndNotification && _dragOpenDrawerMode == _DragOpenDrawerMode.done){
_changeDragOpenDrawerMode(_DragOpenDrawerMode.opened);
}
return true;
},
child: child ?? SizedBox()),
);
},
child:Container(
color: Colors.white,
height: _maxHeight,
child: widget.child
),
),
],
),
);
},
);
}
_changeDragOpenDrawerMode(_DragOpenDrawerMode newMode)async{
_dragOpenDrawerMode = newMode;
switch (newMode){
case _DragOpenDrawerMode.canceled : {
_controller.duration = widget.closeDuration;
await _controller.reverse();
_openTriggered = false;
_dragOffset = .0;
break;
}
case _DragOpenDrawerMode.dragging:
_controller.duration = Duration(seconds: 0);
await _controller.animateTo(_dragOffset/_maxHeight);
break;
case _DragOpenDrawerMode.opened:
_controller.duration = widget.openDuration;
await _controller.forward();
break;
case _DragOpenDrawerMode.done:
if(!_openTriggered){
widget.onOpen!.call();
}
_openTriggered = true;
break;
default:
//executeUnknown();
}
}
}
到此这篇关于flutter实现一个列表下拉抽屉的示例代码的文章就介绍到这了,更多相关flutter 列表下拉抽屉内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: flutter实现一个列表下拉抽屉的示例代码
本文链接: https://lsjlt.com/news/139432.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-21
2023-10-28
2023-10-28
2023-10-27
2023-10-27
2023-10-27
2023-10-27
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0