flutter实现一个列表下拉抽屉的示例代码

本文主要介绍了flutter实现一个列表下拉抽屉的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

使用

通过监听滚动事件实现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],);   }, ),

组件参数说明

  • openDuration:抽屉打开动画持续的时间
  • closeDuration: 抽屉关闭动画持续的时间
  • onOpen: 抽屉打开事件回调
  • child: DragOpenDrawer 组件监听的滚动组件
  • backgroundBuilder:抽屉打开后展示的组件

运行效果

源码

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 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 列表下拉抽屉内容请搜索0133技术站以前的文章或继续浏览下面的相关文章希望大家以后多多支持0133技术站!

以上就是flutter实现一个列表下拉抽屉的示例代码的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » 移动