📄
FlutterCheatSheet
  • About
  • Flutter web
    • Download in flutter web
    • Fluter run web selain chrome
    • Mengatasi CORS
  • My Note
    • Cara mudah setting Firebase
    • solusi text overflow
    • Setting Firebase Mobile
    • Setting MinSDK Android
    • Run build runner
    • Load Json FromAsset
    • Set Height TabBar
    • WillPopScope
    • Dropdown with null
    • Interview Flutter
    • shortcut android studio
    • Build with different main.dart
    • Validating email
    • search delay
    • Hive
    • penggunaan sort maupun func lain
    • incompatible version of Kotlin.
    • Google Signin error
    • add Map to Map
    • Cors Anywhere
    • run scrcpy simple
    • android studio adb server version (41) doesn't match this client (39); killing
    • Connect adb with hotspot
    • Bloc , intinya...
    • Restorable state
    • Custom Theme DatePicker Flutter
    • membungkus widget dengan tema
    • All About Extention
    • Provider watch read
    • Provider , App works in debug mode but does not work in release mode
    • make extention
    • Sliver app bar
    • Custom Error screen
    • Rename Package
    • error build on AndroidStudio from vscode
    • add tooltip to all widget
    • Textformfield validator
    • Membuat String Rupiah
    • Sort List Dart
    • chart
    • membuat Date time lokal
    • Change default PageTransition
    • Show Hide Password
    • Error UserFriendly
    • Responsive adaptive layout
    • Tips SingleScrollingView
    • Build context
    • FittedBox
    • validation
      • Dropdown validation
    • alertDialog
      • Mixin
      • FocusNode
      • WebView url listener
      • tips statefull pada alertdialog
      • run-code-after-showdialog-is-dismissed
    • Set package in VS Code when creating a project
  • Usefull source
    • Setting JAVA_HOME
    • Tools for Flutter
    • WEBVIEW
    • membuat Marque
    • LazyLoad
    • Tips
      • Penggunaan Const
      • 3 Dots
      • How Disable all Widget
    • List article
    • List Web Complete Tutorial
    • List library
    • Parsing nested Json
    • Future
      • Tips Clean Code
      • Custom Future
      • Chaining Future
      • Catch error
    • Flutter Sample HTTP Request Github with https://reqres.in/
    • Const vs Final
    • Constructor
    • Function
    • Font
    • CRUD
    • Key
    • Free bootcamp
    • State Manajement
      • Provider
  • Widgets
    • Top 5 Box widget
    • Framework library
      • GetFlutter
      • FLUI
    • kumpulan widget
      • Spacer
      • ClipRRect
      • Switch
      • FittedBox
      • List dari Model
      • Dropdown
        • DropDown Multi
    • Deep Dive
      • Button
      • Card
      • Flexible and Expanded
      • Layout Builder
  • Interview Question
    • Kumpulan Pertannyaan Interview
      • Interview Question link Flutter
      • Interview Question With Answer
  • kasus dari stackoverflow
    • Text Red in Hero
    • firebase issued
    • Untitled
  • library
    • Rapido
    • autoscroll text
Powered by GitBook
On this page
  • Watch Youtube Tutorial
  • Add Dependencies First
  • Aim:
  • What if I have More Notifiers?
  • Complete Source Code

Was this helpful?

  1. Usefull source
  2. State Manajement

Provider

PreviousState ManajementNextTop 5 Box widget

Last updated 5 years ago

Was this helpful?

With Providers and MultiProviders we can do easy StateManagement in Flutter.State Management in Flutter using Provider

Watch Youtube Tutorial

State Management In Flutter made Easy

Add Dependencies First

Go to your pubspec.yaml file add the below dependency,

I would recommend to add the latest dependency version, at this moment it is 4.0.4

provider: ^4.0.4

The Providers will have

  1. ChangeNotifiers

  2. ChangeNotifierProviders

  3. Consumers

The Basic flow to update a state in Provider is to call notifyListeners() on the Listener class which in turn calls the Change Notifier and then the corresponding model Consumer widget will be triggered with the Model Data.

So Don’t get confused, it’s really easy. Let’s see how that works.

So we have two screens here 1. Home Screen 2. Add Items Screen

Aim:

We will be creating a Shopping List here and the user should be able to add data to the Shopping list from anywhere in the Flutter Application.

The Add Items Screen will have a Textfield and a button. When the user hits the button, he/she should be able to add data from the Add Item screen to the Home Screen and update the Shopping List in the Home Screen.

This can be achieved with the help of Providers.

First thing I need is a Notifier class for each of my DataModel.

Our model is called ‘Item’

class Item {
  String itemName;
  Item(this.itemName);
}

We also need a Notifier class named “ItemAddNotifier” which will look like this

import 'package:flutter/material.dart';
import 'Item.dart';class ItemAddNotifier extends ChangeNotifier {
  //
  List<Item> itemList = [];addItem(String itemName) async {
    Item item = Item(itemName);
    itemList.add(item);    notifyListeners();
  }
}

So this is an individual class and we have not linked it to anything yet.

In the above class, you can see that it has extended ‘ChangeNotifier’ which means whenever there is some trigger for this model from anywhere in the application for the model ‘ItemAddNotifier’, this class will be triggered.

Let’ check this in the AddItemScreen class below

Create a new File named AddItemScreen.dart

Here is the build method for this screen.

We are opening this screen from the Home Screen, and the Add Item button on this screen will close this screen and return to HomeScreen.

 TextField(
    controller: _itemNameController,
    decoration: InputDecoration(
      contentPadding: EdgeInsets.all(15.0),
      hintText: 'Item Name',
    ),
  ),
  SizedBox(
    height: 20.0,
  ),
  RaisedButton(
    child: Text('ADD ITEM'),
    onPressed: () async {
      if (_itemNameController.text.isEmpty) {
        return;
      }
      await Provider.of<ItemAddNotifier>(context, listen: false)
          .addItem(_itemNameController.text);
      Navigator.pop(context);
    },
  )

Here you can see we are calling

Provider.of<ItemAddNotifier>(context)
 .addItem(_itemNameController.text);

_itemNameController is the controller for the TextField.

This code will trigger the ‘ItemAddNotifier’ class and then you will have access to all the methods inside ‘ItemAddNotifier’ class. As you can see the above code the ‘addItem’ method is being called which calls the ‘addItem’ method in the ‘ItemAddNotifier’ class and add it to the data to the itemList in the class and then we are calling the important method ‘notifyListeners()’ which notifiers the ChangeNotifier that we have not written yet. Let’s write that.

So here we want to use the ItemAddNotifier across the application, not only for the HomeScreen.

For this reason, we need to add the ChangeNotifierProvider to the root of the Application.

Let’s go to the main.dart file which is the entry point of your Flutter Application.

So here the main.dart file will look like this.

import 'package:flutter/material.dart';
import 'package:flutter_demos/Provider/ItemAddNotifier.dart';
import 'package:flutter_demos/Provider/ShopNameNotifier.dart';
import 'package:provider/provider.dart';
import 'Provider/HomeScreen.dart';void main() {
  runApp(HomeApp());
}class HomeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<ItemAddNotifier>(
      create: (BuildContext context) {
        return ItemAddNotifier();
      },
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: HomeScreen(),
      ),
    );
  }
}

In the above code, we are wrapping the whole Root Widget which is the MaterialApp widget inside the ‘ChangeNotifier’ widget. This makes sure that the whole application receives the updates whenever there is a change in the Shopping List.

Now it’s time to receive the Data anywhere in the application. In this example, we will consume it in the HomeScreen. The ‘Consumer’ widget with the correct ‘Notifier Class’ consumes the corresponding data. Here our Notifier is ‘ItemAddNotifier’

HomeScreen

import 'package:flutter/material.dart';
import 'package:flutter_demos/Provider/AddItemScreen.dart';
import 'package:flutter_demos/Provider/ItemAddNotifier.dart';
import 'package:flutter_demos/Provider/ShopNameNotifier.dart';
import 'package:provider/provider.dart';class HomeScreen extends StatelessWidget {
  //
  HomeScreen() : super();final String title = 'Home';@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.add),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  fullscreenDialog: true,
                  builder: (context) {
                    return AddItemsScreen();
                  },
                ),
              );
            },
          )
        ],
      ),
      body: Container(
        padding: EdgeInsets.all(30.0),
        child: Column(
          children: <Widget>[
            Expanded(
              child: Consumer<ItemAddNotifier>(
                builder: (context, itemAddNotifier, _) {
                  return ListView.builder(
                    itemCount: itemAddNotifier.itemList.length,
                    itemBuilder: (context, index) {
                      return Padding(
                        padding: EdgeInsets.all(15.0),
                        child: Text(
                          itemAddNotifier.itemList[index].itemName,
                          style: TextStyle(
                            fontSize: 20.0,
                            color: Colors.black,
                          ),
                        ),
                      );
                    },
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

In the above code you can see the ‘Consumer’ widget

Consumer<ItemAddNotifier>(
                builder: (context, itemAddNotifier, _) {

Here the second parameter is our Notifier. From the parameter you can access all the members in the Notifier class.

itemAddNotifier.itemList // like this

And That’s it.

Advantages

  1. Whenever there is change in data for this Model, only the Consumer widget corresponding to that Model will be rebuilt results in improved Performance.

  2. You can have any number of Consumers and update anywhere from the application, and use less setState().

What if I have More Notifiers?

This is absolutely possible that you will have more than one data model and corresponding notifiers, in that case you can use ‘MultiProviders’.

Let’s say I have a ShopNameNotifier which looks something like this

import 'package:flutter/material.dart';class ShopNameNotifier extends ChangeNotifier {
  //
  String shopName = '';updateShopName(String shopName) async {
    this.shopName = shopName;
    notifyListeners();
  }
}

So to add the Change Notifier, we will update the main.dart like this

import 'package:flutter/material.dart';
import 'package:flutter_demos/Provider/ItemAddNotifier.dart';
import 'package:flutter_demos/Provider/ShopNameNotifier.dart';
import 'package:provider/provider.dart';
import 'Provider/HomeScreen.dart';void main() {
  runApp(HomeApp());
}class HomeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<ItemAddNotifier>(
          create: (BuildContext context) {
            return ItemAddNotifier();
          },
        ),
        ChangeNotifierProvider<ShopNameNotifier>(
          create: (BuildContext context) {
            return ShopNameNotifier();
          },
        )
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: HomeScreen(),
      ),
    );
  }
}

Here you can see we added the ‘MultiProvider’ widget with two ‘ChangeNotifierProvider’ with two models.

To Update the ShopName, call like below from any class.

Provider.of<ShopNameNotifier>(context)
    .updateShopName('Shop One');

And to Consume the data is simple,

Consumer<ShopNameNotifier>(
  builder: (context, shopNameNotifier, _) {
    return Text('Shop Name: ${shopNameNotifier.shopName}');
  },
),

Thats it!!!

Complete Source Code

Add Item Screen

Done, So you can see we are using setState() nowhere in the application.Shopping List Screen

https://bitbucket.org/vipinvijayan1987/tutorialprojects/src/ProviderDemo/FlutterTutorialProjects/flutter_demos/
Vipin Vijayan