Flutter 聚焦输入框放大的过渡动画实现

18 min read

Flutter 的过渡动画实现相对简单,一般需要以下几个步骤:

  1. 定义动画控制器

Flutter 的动画控制器用于控制动画的起始值和终止值、动画的播放速度等。动画控制器有多种类型,常用的有 AnimationController 和 Animation。其中,AnimationController 控制动画的持续时间、起始值和终止值,而 Animation 控制动画的中间值。

  1. 定义 Tween

Tween 是一个动画值变化的插值器,它用于表示动画值的起始值和终止值。Tween 通常用于控制动画效果的过渡方式,例如线性、曲线等。

  1. 定义 Animation

Animation 是一个描述动画值的对象,它包含当前动画的值和动画的状态信息。Animation 接收一个 Tween 和一个 AnimationController,它用于计算当前动画的值,并根据这个值更新动画视图。

  1. 定义动画监听器

定义动画监听器可以监控动画的状态,例如动画开始、结束等状态。动画监听器通常使用 AnimatedBuilder,它可以方便地将动画值更新到界面上。

以上是 Flutter 动画的基本步骤,下面介绍一下如何实现输入框放大的过渡动画。

首先,我们需要定义一个输入框。输入框可以使用 Flutter 提供的 TextField 组件。在 TextField 的外层包裹一个容器,用于放大和缩小动画的过渡。

Container(
  width: 200,
  height: 50,
  child: TextField(
    decoration: InputDecoration(
      hintText: '请输入',
      border: OutlineInputBorder(
        borderRadius: BorderRadius.circular(25.0),
      ),
    ),
  ),
);

接下来,我们定义一个动画控制器和一个 Animation。动画控制器控制动画的时间和状态,Animation 定义动画的起始值和终止值。

AnimationController _controller;
Animation<double> _animation;
double _scale;
 
@override
void initState() {
  _controller = AnimationController(
      vsync: this, duration: Duration(milliseconds: 300));
  _scale = 1.0;
  _animation = Tween<double>(begin: 1.0, end: 1.5).animate(_controller)
    ..addListener(() {
      setState(() {
        _scale = _animation.value;
      });
    });
  super.initState();
}

上面代码中定义了 _controller 和 _animation 两个变量,_scale 变量用于保存动画的值,在动画过程中实时更新界面。初始化时设置 _scale = 1.0,表示无动画效果。

接着,我们在输入框上添加一个 GestureDetector,用于触发动画效果。

GestureDetector(
  onTapDown: (_) {
    _controller.forward();
  },
  onTapUp: (_) {
    _controller.reverse();
  },
  onTapCancel: () {
    _controller.reverse();
  },
  child: Transform.scale(
    scale: _scale,
    child: Container(
      width: 200,
      height: 50,
      child: TextField(
        decoration: InputDecoration(
          hintText: '请输入',
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(25.0),
          ),
        ),
      ),
    ),
  ),
)

上面代码中,我们添加一个 GestureDetector,设置 onTapDown、onTapUp 和 onTapCancel 事件的回调函数。这些回调函数用于启动和停止动画。在 GestureDetector 的 child 属性中,我们使用 Transform.scale 组件,缩放输入框的大小,实现放大和缩小的动画效果。

最后,将上述代码添加到 StatefulWidget 中的 build 函数即可。

@override
Widget build(BuildContext context) {
  return MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: Text('Flutter transition animation')),
      body: Center(
        child: GestureDetector(
          onTapDown: (_) {
            _controller.forward();
          },
          onTapUp: (_) {
            _controller.reverse();
          },
          onTapCancel: () {
            _controller.reverse();
          },
          child: Transform.scale(
            scale: _scale,
            child: Container(
              width: 200,
              height: 50,
              child: TextField(
                decoration: InputDecoration(
                  hintText: '请输入',
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(25.0),
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
    ),
  );
}

这样,我们就实现了输入框放大的过渡动画。完整代码如下: