Ah-hoc stateful widgets using StatefullBuilder

Flutter Aug 21, 2021

Flutter and its declarative paradigm is quite great. The declarative way of building UIs means you only need to "bind" properties to elements.

As long as you update your property's value inside setState() of a StatefulWidget, the value will magically be reflected in the UI.

But what happens when you have a Widget that accepts a builder and you need to have something that has a state? Sure, you can just create a new StatefulWidget and return that from the builder. But this might be too verbose if you want to build something small.

This is where StatefulBuilder comes into play. It's a widget that provides a StateSetter to be able to call the familiar setState() when building a widget "ad-hoc" (e.g. from a builder).

Let me give you an example and explain it line by line. The showModalBottomSheet is a convenient method for showing a dialog popping up from the bottom of the screen. This method has a builder parameter to build the widget for the content of this dialog.

void openModal(
        BuildContext context, MyViewModel viewModel) => // 1.
    showModalBottomSheet<void>(
        context: context,
        builder: (BuildContext context) => StatefulBuilder( // 2.
            builder: (BuildContext context, StateSetter setState) => // 3.
              TextButton(
                child: Text(viewModel.counter.toString()),
                onPressed: () => setState(() => viewModel.counter++)))); // 4.
  1. The approach of using a StatefulBuilder described here has the caveat that the state should be stored outside of the builder (e.g. in a ViewModel) since the builder will be called every time the setState() is called.
  2. The showModalBottomSheet() method has a builder parameter for the content of the modal. Here is where we return our StatefullBuilder.
  3. The StatefulBuilder's builder provides the StateSetter we will use it later when we want to update the contents of the modal.
  4. In the onPressed we don't just update our data. Instead, we update our data inside the familiar setState(). The StatefulBuilder's builder will be called again and the content of the modal will be updated.

Hopefully, by now it's clear how to return stateful widgets in  builders without creating new StatefulWidgets, but by using  the StatefullBuilder.

Happy coding!

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.