Home > Software engineering >  How to animate row when children changes
How to animate row when children changes

Time:09-02

How do you achieve the smooth transition when the checkmark is added?

enter image description here

Clicking the element will setState update the pressAttention variable, and therefore add the checkmark widget to the list of children of the row. For now it just instantly rebuilds the row, and adds the checkmark, but I would really like it to smoothly do as in the GIF.

Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: <Widget>[
    Text(
      widget.amount,
      style: const TextStyle(
          color: Colors.white, fontWeight: FontWeight.w700),
    ),
    if (pressAttention)
      Padding(
        padding: const EdgeInsets.only(left: 10),
        child: Container(
          width: 23,
          height: 23,
          decoration: BoxDecoration(
            color: Theme.of(context).highlightColor,
            shape: BoxShape.circle,
          ),
          child: Padding(
            padding: const EdgeInsets.all(4),
            child: SvgPicture.asset(
              MyIcons.checkmarkThick,
            ),
          ),
        ),
      )
  ],
),

CodePudding user response:

You can achieve this with a combination of Animated Widgets. Set their behaviours and durations and you should be good to go.

CodePudding user response:

try this:

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  late Animation<double> _animation;
  late Animation<double> _opacityAnimation;
  late Animation _colorAnimation;
  late AnimationController _controller;

  var pressAttention = false;

  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(duration: Duration(milliseconds: 500), vsync: this)
          ..addListener(() => setState(() {}));
    _animation = Tween(begin: 15.0, end: 0.0).animate(_controller);
    _opacityAnimation = Tween(begin: 0.0, end: 1.0).animate(_controller);

    _colorAnimation =
        ColorTween(begin: Colors.grey, end: Colors.purple).animate(_controller);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Center(
        child: Center(
          child: Container(
            child: InkWell(
              splashColor: Colors.transparent,
              highlightColor: Colors.transparent,
              onTap: () {
                if (pressAttention) {
                  _controller.forward();
                } else {
                  _controller.reverse();
                }
                setState(() {
                  pressAttention = !pressAttention;
                });
              },
              child: AnimatedBuilder(
                  animation: _controller,
                  builder: (context, child) {
                    return Container(
                      width: 100,
                      decoration: BoxDecoration(
                        border: Border.all(color: _colorAnimation.value),
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Transform.translate(
                            offset: Offset(_animation.value, 0),
                            child: Text(
                              '1000',
                              style: const TextStyle(
                                  color: Colors.white,
                                  fontWeight: FontWeight.w700),
                            ),
                          ),
                          Opacity(
                            opacity: _opacityAnimation.value,
                            child: Padding(
                              padding: EdgeInsets.only(left: 10),
                              child: Container(
                                decoration: BoxDecoration(
                                  color: Theme.of(context).highlightColor,
                                  shape: BoxShape.circle,
                                ),
                                child: const Padding(
                                  padding: EdgeInsets.all(4),
                                  child: Icon(
                                    Icons.check,
                                    size: 13,
                                  ),
                                ),
                              ),
                            ),
                          )
                        ],
                      ),
                    );
                  }),
            ),
          ),
        ),
      ),
    );
  }
}
  • Related