State createState() => HomePageState();
}
class HomePageState extends State
with SingleTickerProviderStateMixin {
@override
void initState() {…}
@override
void dispose() {…}
@override
Widget build(BuildContext context) {…}
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
最后
我一直以来都有整理练习大厂面试题的习惯,有随时跳出舒服圈的准备,也许求职者已经很满意现在的工作,薪酬,觉得习惯而且安逸。
不过如果公司突然倒闭,或者部门被裁减,还能找到这样或者更好的工作吗?
我建议各位,多刷刷面试题,知道最新的技术,每三个月可以去面试一两家公司,因为你已经有不错的工作了,所以可以带着轻松的心态去面试,同时也可以增加面试的经验。
我可以将最近整理的一线互联网公司面试真题+解析分享给大家,大概花了三个月的时间整理2246页,帮助大家学习进步。
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!以下是部分内容截图:
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
714965310821)]
[外链图片转存中…(img-O55FvkEH-1714965310823)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!