简介

之前咱们提到了flutter提供了比较简单好用的AnimatedContainer和SlideTransition来进行一些简略的动画成果,然而要齐全实现自定义的简单的动画成果,还是要应用AnimationController。

明天咱们来尝试应用AnimationController来实现一个拖拽图片,而后返回原点的动画。

构建一个要动画的widget

在本文的例子中,咱们心愿可能让一个图片能够实现拖拽而后主动返回原来地位的成果。

为了实现这个性能,咱们首先构建一个放在界面两头的图片。

      child: Align(        alignment: Alignment.center,        child: Card(          child: Image(image: AssetImage('images/head.jpg'))        ),      )

这里应用了Align组件,将一个图片对象放在界面两头。

接下来咱们心愿这个widget能够拖拽,那么把这个child放到一个GestureDetector中,这样就能够相应拖拽对应的响应。

 Widget build(BuildContext context) {    final size = MediaQuery.of(context).size;    return GestureDetector(      onPanUpdate: (details) {        setState(() {          _animateAlign += Alignment(            details.delta.dx / (size.width / 2),            details.delta.dy / (size.height / 2),          );        });      },      child: Align(        alignment: _animateAlign,        child: Card(          child: widget.child,        ),      ),    );  }

为了能实现拖动的成果,咱们须要在GestureDetector的onPanUpdate办法中对Align的地位进行批改,所以咱们须要调用setState办法。

在setState办法中,咱们依据手势的地位来调整Alignment的地位,所以这里须要用到MediaQuery来获取屏幕的大小。

然而当初实现的成果是图像随手势挪动而挪动,咱们还须要实现在手放开之后,图像主动回复到原来地位的动画成果。

让图像动起来

因为这次须要变动的是Alignment,所以咱们先定义一个蕴含Alignment的Animation属性:

  late Animation<Alignment> _animation;

接下来咱们须要定义一个AnimationController,用来管制动画信息,并且指定咱们须要的动画终点和起点:

  late AnimationController _controller;      _animation = _controller.drive(      AlignmentTween(        begin: _animateAlign,        end: Alignment.center,      ),    );

咱们动画的终点地位就是以后image所在的Alignment,起点就在Alignment.center。

Alignment有一个专门示意地位信息的类叫做AlignmentTween,如上代码所示。

有了终点和起点, 咱们还须要指定从终点挪动到起点的形式,这里模仿应用弹簧成果,所以应用SpringSimulation。

SpringSimulation须要提供对spring的形容,终点间隔,完结间隔和初始速度。

    const spring = SpringDescription(      mass: 30,      stiffness: 1,      damping: 1,    );    final simulation = SpringSimulation(spring, 0, 1, -1);

咱们应用下面创立的simulation,来实现动画:

    _controller.animateWith(simulation);

最初咱们须要在手势完结的时候来执行这个动画即可:

      onPanEnd: (details) {        _runAnimation();      },

最初,运行成果如下所示:

总结

AnimationController是一个很弱小的组件,然而应用起来也不是那么的简单, 咱们只须要定义好终点和起点,而后指定动画成果即可。

本文的例子:https://github.com/ddean2009/learn-flutter.git