Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a smooth animation when widgets change?

I want to make a smooth animation for my widgets: small floating icon button and big blue square. Here is my prototype code.

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (context, child) {
        return Scaffold(body: Stack(children: [AnimatedWidget()]));
      },
    );
  }
}

class AnimatedWidget extends StatefulWidget {
  const AnimatedWidget({super.key});

  @override
  AnimatedWidgetState createState() => AnimatedWidgetState();
}

class AnimatedWidgetState extends State<AnimatedWidget> {
  bool _isOpen = false;

  void toggleButton() {
    setState(() {
      _isOpen = !_isOpen;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      bottom: 20,
      right: 20,
      child: AnimatedSwitcher(
        duration: Duration(milliseconds: 200),
        transitionBuilder: (child, animation) {
          return FadeTransition(
            opacity: animation.drive(Tween(begin: 0.0, end: 1.0)),
            child: ScaleTransition(scale: animation, child: child),
          );
        },
        child:
            _isOpen
                ? Column(
                  key: ValueKey('square'),
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    GestureDetector(onTap: toggleButton, child: Row(children: [Text('Close'), Icon(Icons.close)])),
                    Container(
                      width: 300,
                      height: 300,
                      decoration: BoxDecoration(color: Colors.blue, shape: BoxShape.rectangle),
                      child: Center(child: Text('This is square')),
                    ),
                  ],
                )
                : FloatingActionButton(key: ValueKey('add'), onPressed: toggleButton, child: Icon(Icons.add)),
      ),
    );
  }
}

There is a flaw in my example. When I click the small button and the animation plays, I can see how the small widget is in the middle of the large widget. But I would like the animation to be smooth and the widgets to transform smoothly. How can I fix this? I will be glad any help.

like image 770
Heike Heinrich Avatar asked Oct 15 '25 16:10

Heike Heinrich


1 Answers

Try to set layoutBuilder to AnimatedSwitcher like this.

child: AnimatedSwitcher(
  // ...

  layoutBuilder: (currentChild, previousChildren) {
    return Stack(
      alignment: Alignment.bottomRight,
      children: <Widget>[...previousChildren, if (currentChild != null) currentChild],
    );
  },

  // ...
),

It's same with defaultLayoutBuilder but only Stack's alignment changed.

like image 148
Leo Avatar answered Oct 18 '25 07:10

Leo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!