EN VI

Flutter - How to replace a child Widget with state?

2024-03-11 03:30:05
Flutter - How to replace a child Widget with state?

I am trying to replace a child StatefulWidget upon pressing a button. It works if the child is a StatelessWidget, and if the StatefulWidget doesn't actually have any state.

I'm relatively new to Flutter and I don't understand why this would happen. In my mind a new Widget (regardless of whether it is Stateless or Stateful) is instantiated with new state, the child Widget is replaced in the setState() method, and the screen should be updated to reflect this.

Can anyone explain this to me?

I have written a short example to better illustrate my issue:

https://dartpad.dev/?id=5de8c8ef70d200d75a324ab85ff5e209

In the above example I would have expected both Containers to change color upon pressing the button.

Solution:

The problem is you are using the same widget for the second time and since you are setting the color inside the initState, the value won't be changed.

You have options like creating a new StatefulWidget, using the key property or using the old Widget with updated value.

Solution 1. To create a new StatefulWidget, you must set the key property like:

activeStatefulWidget = SimpleStatefulWidget(
  key: ValueKey(Random().nextInt(100)),
  color: Colors.blue,
);

Of course the key must be a unique value. In your example, widgets have different color so you can use: key: ValueKey(Colors.blue.toString()),. For more information, take a look at: Key class and Widget key

Solution 2. Update the value you created inside the StatefulWidget

@override
void didUpdateWidget(covariant SimpleStatefulWidget oldWidget) {
   color = widget.color;
   super.didUpdateWidget(oldWidget);
}

Solution 3. Use widget.color inside build method:

@override
Widget build(BuildContext context) {
 return Container(
  color: widget.color,
  width: 100,
  height: 100,
 );
}
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login