首页 > 解决方案 > Flutter - 如何向 Widget 添加动画,以便在按下按钮时滑入视图?

问题描述

让我们做一个简单的例子,给定一个Column(),我有 2 个容器,一个button.

Column(
 children: [
   MyButton(
    label: "Expand me"
    onTap: () => setState(() => isOpen = !isOpen) 
   ),
   Container(
    child: Text("Container 1"),
    height: 200
  ),
   if (isOpen)
   Container(
    child: Text("Container 2"),
    height: 150
   )
 ]
)

所以基本上,如果我们按下按钮,第二个Container就会出现在第一个的正下方,就像一个扩展面板。

现在我想添加一个动画,我很难找到最适合我的用例的,因为对于这样一个简单的任务,大多数解决方案看起来真的很复杂。

动画真的很简单,Container 2与其让第一个动画下面突然出现,不如Container 2从后面开始Container 1,然后向底部滑动,直到就位。

在颤动中实现这一目标的最干净的方法是什么?

标签: flutteranimation

解决方案


 import 'package:flutter/material.dart';
    
    // ignore: must_be_immutable
    class EasyAnimatedOffset extends StatefulWidget {
      EasyAnimatedOffset();
    
      @override
      _EasyAnimatedOffsetState createState() => _EasyAnimatedOffsetState();
    }
    
    class _EasyAnimatedOffsetState extends State<EasyAnimatedOffset>
     
        with SingleTickerProviderStateMixin {
      //Notice the "SingleTickerProviderStateMixin" above
      //Must add "AnimationController"
      late AnimationController _animationController;
    
      @override
      void initState() {
        super.initState();
        _animationController = AnimationController(
          vsync: this,
          //change the animation duration for a slower or faster animation.
          //For example, replacing 1000 with 5000 will give you a 5x slower animation.
          duration: Duration(milliseconds: 1000),
        );
      }
    
      animateForward() {
        _animationController.forward();
        //this controller will move the animation forward
        //you can also create a reverse animation using "_animationController.reverse()"
      }
    
      @override
      void dispose() {
        _animationController.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        //the offset has a x value and y value.
        //changing the y axis value moves the animation vertically
        //changing the x axis value moves the animation horizantaly
        double xAxisValue = 0;
        double yAxisValue = 10;
        return AnimatedBuilder(
            animation: _animationController,
            // child: widget.child,
            builder: (context, child) {
              return Transform.translate(
                  offset: Offset(_animationController.value * xAxisValue,
                      _animationController.value * yAxisValue),
                   //add your button or widget here
                  child: InkWell(

                      onTap: () {
                        animateForward();
                      },
    
                      child: Center(
                        child: Container(
                            height: 100,
                            width: 200,
                            color: Colors.amber,
                            child: Center(
                              child: Text(
                                "Animate Me",
                                style: TextStyle(
                                  color: Colors.black,
                                  fontSize: 20,
                                ),
                              ),
                            )),
                      )));
            });
      }
    }

推荐阅读