Select Page

State Management using ValueNotifier and ValueListenableBuilder for Dashboard App

Dashboard using ValueNotifier and ValueListenableBuilder.
State Management by using built-in Flutter classes.

     

    What is State Management?

    State Management is not a simple topic. How do you know if you need it? Usually, once you start developing an application you will run into this issue, how do I manage the state of data, how do I access data from different parts of the app?

    We have ephemeral and app state that we can use. An ephemeral state is a local state that lives in a single widget, like a single page of the application. App state can be global, app-wide state that is shared in different parts of the app.

    There is no definite way to handle state management, this is something that you need to decide depending on your needs and likes. On a simple application, the default setState() can manage to refresh the page, but what if the page has many widgets/parts that need to redraw, you do not want to refresh the entire page because it will cause that janky animation. In those cases you only want to redraw each widget as needed, therefore increasing performance.

     

    Video Tutorial

    Video Tutorial: YouTube Video

    Source Code: GitHub

     

     

     

    What is covered

     

    In this project, you are going to take a look at:

    • How to use ValueNotifier and ValueListenableBuilder to pass data from a parent (ancestor) widget to child (descendant) widgets in the widget tree
    • State Management with build-in classes, no packages

     

     

    The Problem:

    • Dashboard app needs to chart espresso, coffee, and latte consumption
    • Drawing each bar, the chart needs to refresh independently for performance

    The Solution:

    • Use the ValueNotifier and ValueListenableBuilder to allow to selectively rebuild individual widgets for performance

     

    ValueNotifier and ValueListenableBuilder

     

    The ValueNotifier and ValueListenableBuilder allow to selectively rebuild individual widgets for performance

    1. Create a class that extends ValueNotifier
    2. Add fields to contain data defining them as ValueNotifier
    3. Add methods to modify data and call the notifyListeners() method
    4. Add the ValueListenableBuilder widget in the widget tree to rebuild widgets selectively if the data changed by individual field
    class DashboardSection {
      ValueNotifier<int> numberOfEspresso = ValueNotifier<int>(0);
      ValueNotifier<int> numberOfCoffee = ValueNotifier<int>(0);
      ValueNotifier<int> numberOfLatte = ValueNotifier<int>(0);
    
      DashboardSection(
          {required this.numberOfEspresso,
            required this.numberOfCoffee,
            required this.numberOfLatte});
    }
    
    class DashboardValueNotifier extends ValueNotifier<DashboardSection> {
      DashboardValueNotifier({required DashboardSection value}) : super(value);
    
      void addNumberOfEspresso(int numberOfEspresso) {
        value.numberOfEspresso.value += numberOfEspresso;
        notifyListeners();
      }
    
      void addNumberOfCoffee(int numberOfCoffee) {
        value.numberOfCoffee.value += numberOfCoffee;
        notifyListeners();
      }
    
      void addNumberOfLatte(int numberOfLatte) {
        value.numberOfLatte.value += numberOfLatte;
        notifyListeners();
      }
    }
    
    // Child Widget
    ValueListenableBuilder(
      valueListenable: dashboardValueNotifier.value.numberOfEspresso,
      builder: (BuildContext context, int value, Widget? child) {
        debugPrint('numberOfEspresso: ${dashboardValueNotifier.value.numberOfEspresso.value}');
          return MoodVerticalBarWidget(
            icon: Icons.coffee_maker_outlined,
            numberToPlot: dashboardValueNotifier.value.numberOfEspresso.value,
            numberToPlotMax: numberToPlotMax,
            title: 'Espresso',
          );
      },
    ),
     

    How it Works

     

    ValueNotifier and ValueListenableBuilder – The ValueNotifier and ValueListenableBuilder allow to selectively rebuild individual widgets for performance. Use fields to contain data defining them as ValueNotifier. Use methods to modify data and call the notifyListeners() method. Use the ValueListenableBuilder widget in the widget tree to rebuild widgets selectively if the data changed by individual field.

     

     

    Pin It on Pinterest