Flutter(九)-实现抽屉动画(4)

void _onViewDragDown(DragDownDetails callback) {…}

void _onViewDrag(DragUpdateDetails callback) {…}

void _onViewDragUp(DragEndDetails callback) {…}
}

初始化状态initState()

这个方法是在Widget初始化的时候系统的回调函数,我们需要在该函数中初始化动画

AnimationController controller;
@override
void initState() {
// 初始化动画控制器,这里限定动画时常为200毫秒
controller = new AnimationController(vsync: this, duration: const Duration(milliseconds: 200));
// vsync对象会绑定动画的定时器到一个可视的widget,所以当widget不显示时,动画定时器将会暂停,当widget再次显示时,动画定时器重新恢复执行,这样就可以避免动画相关UI不在当前屏幕时消耗资源。
// 当使用vsync: this的时候,State对象必须with SingleTickerProviderStateMixin或TickerProviderStateMixin;TickerProviderStateMixin适用于多AnimationController的情况。

// 设置动画曲线,就是动画插值器
// 通过这个链接可以了解更多差值器,https://docs.flutter.io/flutter/animation/Curves-class.html,我们这里使用带回弹效果的bounceOut。
CurvedAnimation curve =
new CurvedAnimation(parent: controller, curve: Curves.bounceOut);

// 增加动画监听,当手势结束的时候通过动态计算到达目标位置的距离实现动画效果。curve.value为当前动画的值,取值范围0~1。
curve.addListener(() {
double animValue = curve.value;
double offset = dragUpDownX - dragDownX;
double toPosition;

// 右滑
if (offset > 0) {
if (offset > maxDragX / 5) {
// 打开
toPosition = maxDragX;
isOpenState = true;
} else {
if (isOpenState) {
toPosition = maxDragX;
isOpenState = true;
} else {
toPosition = 0.0;
isOpenState = false;
}
}
} else {
if (offset < (-maxDragX / 2.0)) {
// 关
toPosition = 0.0;
isOpenState = false;
} else {
if (isOpenState) {
toPosition = maxDragX;
isOpenState = true;
} else {
toPosition = 0.0;
isOpenState = false;
}
}
}

dragOffset = (toPosition - dragUpDownX) * animValue + dragUpDownX;
// 刷新位置
setState(() {});
});
}

结束Widget dispose()

当Widget不可用将被回收的时候,系统会回调dispose()方法,我们在这里回收动画。

@override
void dispose() {
controller.dispose();
}

记录按下的位置

double dragDownX = 0.0;
void _onViewDragDown(DragDownDetails callback) {
dragDownX = callback.globalPosition.dx;
}

拖动的时候刷新View的位置

/**

  • 最大可拖动位置
    */
    final double maxDragX = 230.0;
    double dragOffset = 0.0;
    void _onViewDrag(DragUpdateDetails callback) {
    double tmpOffset = callback.globalPosition.dx - dragDownX;

if (tmpOffset < 0) {
tmpOffset += maxDragX;
}

// 边缘检测
if (tmpOffset < 0) {
tmpOffset = 0.0;
} else if (tmpOffset >= maxDragX) {
tmpOffset = maxDragX;
}

// 刷新
if (dragOffset != tmpOffset) {
dragOffset = tmpOffset;
setState(() {});
}
}

离手的时候记录位置并执行动画

/**

  • 脱手时候的位置
    */
    double dragUpDownX = 0.0;
    void _onViewDragUp(DragEndDetails callback) {
    dragUpDownX = dragOffset;
    // 执行动画,每次都从第0帧开始执行
    controller.forward(from: 0.0);
    }

支持移动的Widget

@override
Widget build(BuildContext context) {
return Transform.translate(
offset: Offset(dragOffset, 0.0),
child: Container(
child: GestureDetector(
onHorizontalDragDown: _onViewDragDown,
onVerticalDragDown: _onViewDragDown,
onHorizontalDragUpdate: _onViewDrag,
onVerticalDragUpdate: _onViewDrag,
onHorizontalDragEnd: _onViewDragUp,
onVerticalDragEnd: _onViewDragUp,
child: Container(
child: new UpDrawerWidget(),

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
门**

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 10
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值