内置的拖动相关组件
1. Draggable 2. DragTarget
对于需要拖动的元素包裹 Draggable 即可,或者使用 LongPressDraggable ,其区别是后者需要长按才能拖动,前者直接可以拖动。对于拖动需要放置到某个目标区域的,使用 DragTarget 组件即可。
通过相关的事件实现
拖动的本质是用户选中某个组件并移动它,所以只要在用户移动手指的过程中,实时的根据用户手指所在位置更新组件渲染位置,便是拖动的效果,只是对于拖到边界、拖动很快时如何处理等细节需要进一步完善。
例如可以通过监听 GestureDetector 的 onPanUpdate 得到用户当前位置的值 。
动画与拖动
拖动与动画并没有直接的逻辑关系,拖动可以有动画也可以没有动画,由于大多数 APP 在拖动时都添加了动画效果,所以拖动与动画经常是同时要处理的。不过,对于拖动的元素本身来说,其不存在动画,因为移动是一个位置到另一个位置的连贯的变化,而且是需要及时响应用户的移动,如果加上动画会导致响应用户移动不及时而画蛇添足。所以这里拖动的动画绝大多数情况是指由于移动一个元素,导致其它元素相对位置发生了改变,对于这些位置变换应用动画的情况。
所以,这里可以撇开拖动,独立讨论动画,因为无论是拖动导致的位置变换,或者是点击按钮等等情况导致的位置变化,都是同一逻辑。
撇开任何 UI 语言来说,动画就是某一物的某一个或某几个属性如何随时间变化的问题,而且这个时间通常是固定的。
所以对于实现动画来说,我们关注三个点:
1. 什么在变化 2. 如何变化 3. 变化的持续时间
接着就是要知道在 Flutter 中,对于动画这一问题具体的解决方案是什么,因为在不同的 UI 语言,都有不同的实现思路。
1. 对于什么在变化,Flutter 它是反过来的,通常我们指定是高度在变化,还是宽度在变化,但是 Flutter 是它不需要指定的,而是给我们一个变化值。当我们实例化 AnimactionController 指定了变化时间、变化的范围,我们可以通过该实例访问动画在运行过程中某一时刻的值 controller.vlaue ,而这个值我们是赋值给高度还是宽度,Flutter 并不关心。当然对于开发者来说,被赋值的属性便是我们所说的什么在变化。很多时候,变化的属性可能不止一个,Flutter 提供了 Tween 来实现这种需求。 2. 对于如何变化,默认的变化方式都是线性的,当我们需要其它方式时可以使用 CurvedAnimation 来做到,其内置了很多常见的变化曲线。 3. 对于变化的持续时间,就是简单的在实例化 Animation 时指定 Duration 即可。