Flutter - Slide Transition between two different sized widgets

Viewed 2405

I am trying to animate between widgets as follows:

AnimatedSwitcher(
                  duration: const Duration(seconds: 1),
                  transitionBuilder: (Widget child, Animation<double> animation) {
                    return SlideTransition(
                      position: Tween(
                          begin: Offset(1.0, 0.0),
                          end: Offset(0.0, 0.0),)
                          .animate(animation),
                      child: child,
                    );
                  },
                  child: Provider.of<UserWidgets>(context, listen: false).renderWidget(context),
                ),

This works fine but for two different sized widgets its not smooth because of OffSet. GIF

1 Answers

Try wrapping both your child widgets inside an Align widget like this,

child: Align(
  alignment: Alignment.topCenter,
  child: Provider.of<UserWidgets>(context, listen: false).renderWidget(context),
)

This should ensure that both your old and new children are always aligned to the topCenter while animating.

Here is the full working example.

class Switcher extends StatefulWidget {
  State<StatefulWidget> createState() => SwitcherS();
}

class SwitcherS extends State<Switcher> {
  bool state = false;

  buildChild (index) => Align(
    alignment: Alignment.topCenter,
    child: Container(
      width: index == 0 ? 100 : 150,
      height: index == 0 ? 200 : 150,
      color:index == 0 ? Colors.deepPurple : Colors.deepOrange,
    ),
   key: ValueKey('$index'));

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => setState(() { state = !state; }),
      child: Padding(
        padding: EdgeInsets.all(24),
        child: AnimatedSwitcher(
          duration: const Duration(seconds: 1),
          transitionBuilder: (Widget child, Animation<double> animation) {
            return SlideTransition(
              position: Tween(
                begin: Offset(1.0, 1.0),
                end: Offset(0.0, 0.0),
              ).animate(animation),
              child: child,
            );
          },
          child: buildChild(state ? 0 : 1),
      ),
    );
  }
}
Related