Flutter - State Management using PROVIDER

Flutter - State Management using PROVIDER

In this tutorial you will see the very basics of implementing "Provider" for State management in your Flutter Applications.

In this tutorial you will see the very basics of implementing "Provider" for State management in your Flutter Applications.

So Let’s get started

Before looking into providers lets see whatsis ChangeNotifier this plugin uses ChangeNotifier to to listen and update any changes.

What is ChangeNotifier

Form docs

A class that can be extended or mixed in that provides a change notification API using [VoidCallback] for notifications.> [ChangeNotifier] is optimized for small numbers (one or two) of listeners. It is O(N) for adding and removing listeners and O(N²) for dispatching notifications (where N is the number of listeners)##

Provider

Existing providers

provider exposes a few different kinds of "provider" for different types of objects.

Let's get started with our code

first things first let add plugin to pubspec.yaml

provider: ^2.0.1
http: ^0.12.0+2

Let's Write our provider class first we name it AppState

import 'package:flutter/material.dart';

class AppState with ChangeNotifier {
  AppState();

  String _displayText = "";

  void setDisplayText(String text) {
    _displayText = text;
    notifyListeners();
  }

  String get getDisplayText => _displayText;
}

Our AppState is extended with ChangeNotifier which is used to notify its listeners when we call notifyListeners()

In the code, we declared two methods setDisplayText and getDisplayText which are used to read and write the value in our state

Now we move to our main.dart

import 'package:flutter/material.dart';
import 'package:flutter_demo_provider/app_state.dart';
import 'package:flutter_demo_provider/text_display.dart';
import 'package:flutter_demo_provider/text_edit.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: ChangeNotifierProvider<AppState>(
          builder: (_) => AppState(),
          child: MyHomePage(),
        ));
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Container(
        padding: const EdgeInsets.all(16.0),
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              TextDisplay(),
              TextEditWidget(),
            ],
          ),
        ),
      ),
    );
  }
}

In the code, we can notice we have used ChangeNotifierProvider which is provided from out provider plugin

It accepts two parameters one is builder and the other is child

return MaterialApp(
 title: 'Flutter Demo',
 theme: ThemeData(
 primarySwatch: Colors.blue,
 ),
 home: ChangeNotifierProvider<AppState>(
 builder: (_) => AppState(),
 child: MyHomePage(),
 ));
}

Inside the MyHomePage we have a Scaffold with Column which has two Widgets TextDisplay() and TextEditWidget()

TextDisplay(),
TextEditWidget(),

Here is out TextDisplay() in text_display.dart

import 'package:flutter/material.dart';
import 'package:flutter_demo_provider/app_state.dart';
import 'package:provider/provider.dart';

class TextDisplay extends StatefulWidget {
  @override
  _TextDisplayState createState() => _TextDisplayState();
}

class _TextDisplayState extends State<TextDisplay> {
  @override
  Widget build(BuildContext context) {
    final appState = Provider.of<AppState>(context);

    return Container(
      padding: const EdgeInsets.all(16.0),
      child: Text(
        appState.getDisplayText,
        style: TextStyle(
          fontSize: 24.0,
        ),
      ),
    );
  }
}

In the above code we see

Widget build(BuildContext context) {
 final appState = Provider.of<AppState>(context);

 return Container(
 padding: const EdgeInsets.all(16.0),
 child: Text(
 appState.getDisplayText,
 style: TextStyle(
 fontSize: 24.0,
 ),
 ),
 );
}
final appState = Provider.of<AppState>(context);

This above line of code will get the provider for listening for any changes optionally we can also opt-out for listening by proving listen: false

final appState = Provider.of<AppState>(context, listen: false);

Now in order to access text, we have a function in our provider called getDisplayText

appState.getDisplayText()

Here is out TextEditWidget() in text_edit.dart

  
import 'package:flutter/material.dart';
import 'package:flutter_demo_provider/app_state.dart';
import 'package:provider/provider.dart';

class TextEditWidget extends StatefulWidget {
  @override
  _TextEditWidgetState createState() => _TextEditWidgetState();
}

class _TextEditWidgetState extends State<TextEditWidget> {
  TextEditingController _textEditingController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    final appState = Provider.of<AppState>(context);

    return Container(
      child: TextField(
        controller: _textEditingController,
        decoration: InputDecoration(
          labelText: "Some Text",
          border: OutlineInputBorder(),
        ),
        onChanged: (changed) => appState.setDisplayText(changed),
        onSubmitted: (submitted) => appState.setDisplayText(submitted),
      ),
    );
  }
}

In the above code, we get our appState inside the build function

final appState = Provider.of<AppState>(context);

In order to manipulate the text in the state we call setDisplayText(text) function

TextField(
 controller: _textEditingController,
 decoration: InputDecoration(
 labelText: "Some Text",
 border: OutlineInputBorder(),
 ),
 onChanged: (changed) => appState.setDisplayText(changed),
 onSubmitted: (submitted) => appState.setDisplayText(submitted),
)

we are updating the state whenever out text is changes

onChanged: (changed) => appState.setDisplayText(changed)

Now we perform network operation

Now inside our app state, we have some additional functions and variables

String _dataUrl = "https://reqres.in/api/users?per_page=20";
String _jsonResonse = "";
bool _isFetching = false;

bool get isFetching => _isFetching;

Future<void> fetchData() async {
 _isFetching = true;
 notifyListeners();

 var response = await http.get(_dataUrl);
 if (response.statusCode == 200) {
 _jsonResonse = response.body;
 }

 _isFetching = false;
 notifyListeners();
}

String get getResponseText => _jsonResonse;

List<dynamic> getResponseJson() {
 if (_jsonResonse.isNotEmpty) {
 Map<String, dynamic> json = jsonDecode(_jsonResonse);
 return json['data'];
 }
 return null;
}

Here we have a few more functions fetchData, getResponseText and getResponseJson

fetchData will perform the network operation and update the variable with the response data (you can parse your JSON to custom model here and save it in a List)

getResponseText will return the plain text response

getResponseJson will convert the response text to a Map and returndata field inside it which is a list of Map

To see the final app_state.dart visit below link

Now inside out MyHomePage widget we add two more widgets to our column

RaisedButton(
 onPressed: () => appState.fetchData(),
 child: Text("Fetch Data from Network"),
),
ResponseDisplay(),

So I am calling appState.fetchData() whenever I press the button now fetchData will take care of all the updating of the state on Github

Here is our ResponseDisplay Widget named response_display.dart

  
import 'package:flutter/material.dart';
import 'package:flutter_demo_provider/app_state.dart';
import 'package:provider/provider.dart';

class ResponseDisplay extends StatefulWidget {
  @override
  _ResponseDisplayState createState() => _ResponseDisplayState();
}

class _ResponseDisplayState extends State<ResponseDisplay> {
  @override
  Widget build(BuildContext context) {
    final appState = Provider.of<AppState>(context);

    return Container(
      padding: const EdgeInsets.all(16.0),
      child: appState.isFetching
          ? CircularProgressIndicator()
          : appState.getResponseJson() != null
              ? ListView.builder(
                  primary: false,
                  shrinkWrap: true,
                  itemCount: appState.getResponseJson().length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      leading: CircleAvatar(
                        backgroundImage: NetworkImage(
                            appState.getResponseJson()[index]['avatar']),
                      ),
                      title: Text(
                        appState.getResponseJson()[index]["first_name"],
                      ),
                    );
                  },
                )
              : Text("Press Button above to fetch data"),
    );
  }
}

Here in the above code we parse the JSON and build a list of data

To get the code it's here on GitHub

ECommerce Mobile App Development | Ecommerce Mobile App Development Services

We are leading ecommerce mobile application development company. Hire our ecommerce mobile app developer for your custom Ecommerce project at competitive rates. **Know about [Top ECommerce Mobile App Development...

We are leading ecommerce mobile application development company. Hire our ecommerce mobile app developer for your custom Ecommerce project at competitive rates.

Know about Top ECommerce Mobile App Development Company

ECommerce Mobile App Development Company in England

ECommerce Mobile App Development Company in England

At [**WebClues Global**](https://www.webcluesglobal.com/ "WebClues Global") we have been working on eCommerce apps for the last 7+ years and have built systems which are secure, reliable and easy to use. We have people who have good knowledge on a...

At WebClues Global we have been working on eCommerce apps for the last 7+ years and have built systems which are secure, reliable and easy to use. We have people who have good knowledge on a wide variety of ecommerce technologies – Magento eCommerce, WooCommerce, Shopify, Drupal Commerce, OpenCart, BigCommerce, Joomla , Prestashop, NopCommerce.

As a top ECommerce Mobile App Development Company in England, We have been in the business of software develop ment for 7+ years and we are a specialist in Team Software Development by following Agile Methods. We provide a range of services on eCommerce app development with the support of our deep web application development and mobile app development expertise.

Mobile App Development Company in USA

Mobile App Development Company in USA

**How [Mobile App Development Company in the USA](https://www.dataeximit.com/mobile-app-development-service/ "Mobile App Development Company in the USA"), can breathe life into Your Amazing Ideas?** Today’s Mobile world mobile apps become one of...

How Mobile App Development Company in the USA, can breathe life into Your Amazing Ideas?

Today’s Mobile world mobile apps become one of the important factors in each and every business whether it may be a product based company or a service-based company.

Data EximIT has a strong team of mobile app developers & programmers who have the qualifications and experience in developing apps across several platforms, including iOS, Android, and PhoneGap and. We give our clients complete flexibility with respect to cutting short or extending projects after the minimum term is complete.

Our Mobile App Development Services Are...

  • Android Application Development
  • iOS Application Development
  • Responsive Web Applications
  • Hybrid Mobile Application Development
  • Xamarin Application Development
  • Mobile UI/UX Design

Contact Our Experts For More Information