1

I have a custom StatefulWidget that I want to use on multiple screens (it's kind of a sidebar). However, I want to preserve the state of the widget when the user navigates from one screen to another.

What's the best way to do that?

My first attempt was to just assign a GlobalKey to the widget and reuse that same key on the second screen - but the problem is that the first screen (the "home route") is still there behind the new screen, causing a multiple widgets are using the same key-error.

My second attempt was to simply override createState and either create a new state or use an existing state if one is provided by the user of the widget, but it didn't seem to work:


  // In MyCustomWidget

  final MyCustomWidgetState initialState;
  final void Function(MyCustomWidgetState state) onStateCreated;

  State<MyCustomWidget> createState(){
    MyCustomWidgetState state;
    if( initialState != null ){
      // If I try to simply use `initialState` here, I get a 
      //  `Failed assertion: 'state._element == null': is not true`, 
      //   probably because the state has already been associated with a widget. 
      // So try "cloning" the state instead
      state = MyCustomWidgetState()
        ..someValue = initialState.someValue
        ..someOtherValue = initialState.someOtherValue;
    }
    else{
      state = MyCustomWidgetState();
      if( onStateCreated != null ) onStateCreated(state);
    }

    return state;
  }


  // Using the widget
  MyCustomWidget(
    onStateCreated: (state) => myCustomWidgetState = state,
    initialState: myCustomWidgetState,
  )  


  // Stored states
  MyCustomWidgetState myCustomWidgetState

  

What happens is that initState is executed again when the state is moved from one widget to another, which initializes things in the State as if it were created the first time.

So what is the best way to store/restore the state of a widget when it is being used on multiple screens and you want it to keep its state after navigating to another screen?

Note that this is a rather simple widget with just a few properties in it's state, nothing complicated, so a simple approach would be preferable. I could of course use some elaborate state management framework to store all the arguments in a model, but for this widget I really want to keep it as simple as possible.

I've seen some widgets using an options argument which contains a lot of properties and could be stored somewhere and passed around to various instances of MyCustomWidget - is that the generally preferred way to go?

Magnus
  • 17,157
  • 19
  • 104
  • 189
  • Since you seem realy experienced, I don't know my answer will help you or not. But did you tried to Widget myCostumWidget = MyCostumWidget(); then when ever you want to reuse it to handover this widget? – MrOrhan Aug 09 '23 at 06:55
  • 1
    You could use a `ChangeNotifierProvider` at the top of the widget tree, manage the state there and use `Consumer` to build `MyCustomWidget` wherever you need it. But other state management solutions can work as well. – Peter Koltai Aug 09 '23 at 07:27
  • Why won't you create an Overlay widget which above all screen, then you may not have to store/restore the state of a widget. [Overlay class](https://api.flutter.dev/flutter/widgets/Overlay-class.html) – Zhentao Aug 09 '23 at 07:54
  • You might get an idea from this answer, checkout https://stackoverflow.com/a/74449286/5882307 – OMi Shah Aug 09 '23 at 07:55

0 Answers0