Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AnimatedSwitcher not working as intended? Widget changing but no animation

Goal: Press a button and have it switch to another page with an animated transition.

For that, I'm using AnimatedSwitcher.

Below is my code:

class WelcomeScreenSwitcher extends State<RandomWords>{
  Widget calledWidget;

  void switchPage(int newNumber, context) {
    if (newNumber == 1) {
      setState(() {calledWidget = welcomeScreen(context);},);
    } else if (newNumber == 2) {
      setState(() {calledWidget = learnMoreScreen(context);},);}
    }

  @override
  Widget build(BuildContext context) {
    if (calledWidget == null) {
      switchPage(1, context);
    }
    return AnimatedSwitcher(
      duration: Duration(milliseconds: 5000),
      child: calledWidget,
    );

  Widget welcomeScreen(context){
    return Scaffold({body: Column(children: [
      RaisedButton(onPressed: () {switchPage(2, context);}, child: Text('B'),),],
        );
      });
    }

  Widget learnMoreScreen(context){
    return Scaffold({body: Column(children: [
      RaisedButton(onPressed: () {switchPage(2, context);}, child: Text('B'),),],
        );
      });
    }
  }

The code is functional. It does actually switch between the two pages, but there's no animation to go with it.

At some point during development, I was getting the animation, but then it just stopped happening and I can't find out why. I don't remember changing anything specific about how I call the AnimatedSwitcher.

If it's of any use, hot reloading also doesn't work anymore. I need to Restart the app to have ANY change register. It used to function properly before beginning work on the AnimatedSwitcher.

like image 275
poultrynews Avatar asked Aug 18 '19 20:08

poultrynews


2 Answers

If the new widget you're switching in, is the same type as previous widget, set the key property to another value to get that animation

for example, this AnimatedSwitcher doesn't work:

  AnimatedSwitcher(
    duration: const Duration(milliseconds: 1000),
    child: (condition)
        ? Container(
            width: 100,
            height: 100,
            color: Colors.red,
          )
        : Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
  );

Because we want to switch between two Containers, and AnimatedSwitcher can't understand the difference of them, so it doesn't animate their switch. If we set different key property in those Containers, then AnimatedSwitcher can understand they are different and does animate their switch.

Just like this:

  AnimatedSwitcher(
    duration: const Duration(milliseconds: 1000),
    child: (condition)
        ? Container(
            key: ValueKey<int>(0),
            width: 100,
            height: 100,
            color: Colors.red,
          )
        : Container(
            key: ValueKey<int>(1),
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
  );
like image 140
Amir Mohammad Mashayekhi Avatar answered Oct 13 '22 13:10

Amir Mohammad Mashayekhi


you can try this

class _AniSwitchState extends State<AniSwitch> {
  Widget calledWidget;

  @override
  Widget build(BuildContext context) {
    void switchPage(int newNumber) {
      if (newNumber == 1) {
        setState(() {calledWidget = WelcomeScreen();},);
      } else if (newNumber == 2) {
        setState(() {calledWidget = LearnMoreScreen();},);}
    }

      if (calledWidget == null) {
        switchPage(1);
      }

    return Column(
      children: <Widget>[
        AnimatedSwitcher(
          duration: Duration(milliseconds: 2000),
          child: calledWidget
        ),
        RaisedButton(
          child: const Text('Increment'),
          onPressed: () {
            setState(() {
              switchPage(2);
            });
          },
        ),
      ],
    );
  }
}

class WelcomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text("Welcome"),
      ],
    );
  }
}

class LearnMoreScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Text("hello world"),
      ],
    );
  }
}
like image 20
key Avatar answered Oct 13 '22 14:10

key