/// 抽屉打开时的回调函数
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();
}
}
}
最后,如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。
**小编在这里祝小伙伴们在未来的日子里都可以 升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰!!**
>
> 不论遇到什么困难,都不应该成为我们放弃的理由!
>
>
>
### 最后:学习总结——Android框架体系架构知识脑图(纯手绘xmind文档)
学完之后,若是想验收效果如何,其实最好的方法就是可自己去总结一下。比如我就会在学习完一个东西之后自己去手绘一份xmind文件的知识梳理大纲脑图,这样也可方便后续的复习,且都是自己的理解,相信随便瞟几眼就能迅速过完整个知识,脑补回来。
下方即为我手绘的Android框架体系架构知识脑图,由于是xmind文件,不好上传,所以小编将其以图片形式导出来传在此处,细节方面不是特别清晰。但可给感兴趣的朋友提供完整的Android框架体系架构知识脑图原件(包括上方的面试解析xmind文档)
![](https://img-blog.csdnimg.cn/img_convert/25b44af7fd253ca47cefa2cdfe22c946.webp?x-oss-process=image/format,png)
除此之外,前文所提及的Alibaba珍藏版 **Android框架体系架构** 手写文档以及一本 **《大话数据结构》** 书籍等等相关的学习笔记文档,也皆可分享给认可的朋友!
——感谢大家伙的认可支持,请注意:点赞+点赞+点赞!!!
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
要这份系统化学习资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618156601)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**