Monday, May 27, 2019

Flutter - Pragmatic state management using provider.

As we know, we have to make a hierarchy of widgets to design a screen in Flutter with help of Stateless and Stateful widgets. As the names suggest, the Stateless widget has no internal state which means once built and can never be modified. On the other side, the Stateful widgets are dynamic and have a state, which we can be modified easily throughout their life-cycle without re-initiation.
flutter-pragmatic-state-management-provider-flowThe state of widget is the information that can be read synchronously when the widget is built and change during the lifetime of the widget.  In order to change widget, you need to update the state object which can be update by using setState() function of Stateful widgets.


In this post, we'll see another way to update screen widget without calling setState() of a widget. We'll use provider package for state management that is recommended by the Flutter team in Google io-2019. It is a dependency injection system that is built with widgets for widgets. With the help of this package, we'll create a small example that will show background color change, as shown below:
flutter-pragmatic-state-management-provider-example


Creating a new Project
1. Create a new project from File ⇒ New Flutter Project with your development IDE.
2. Now,  add provider: ^2.0.0+1 Flutter plugin as a dependency in the pubspec.yaml file.
3. After that open main.dart file and edit it. As you see, we have created a tree of widgets. Inside the material app, we’ll wrap our homepage widget with ChangeNotifierProvider. Builder is the actual state object where we’ll instantiate our class.

main.dart
import 'package:counterprovider/color_manager.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: ChangeNotifierProvider<ColorManager>( builder: (context) => ColorManager( 0, 0, 0, ), child: HomePage(), ), ); } } class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { final colorManager = Provider.of<ColorManager>(context); return Scaffold( appBar: AppBar( title: Text("Provider Demo"), ), body: Consumer<ColorManager>( builder: (context, color, _) => Container( height: double.infinity, color: Color.fromARGB( 255, color.getRed(), color.getGreen(), color.getBlue()), width: double.infinity, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( '${color.getRed()}', style: TextStyle(color: Colors.white,fontSize: 20.0), ), SizedBox(width: 10), Text( '${color.getGreen()}', style: TextStyle(color: Colors.white,fontSize: 20.0), ), SizedBox(width: 10), Text( '${color.getBlue()}', style: TextStyle(color: Colors.white,fontSize: 20.0), ), ], ), ), ), floatingActionButton: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.end, children: <Widget>[ FloatingActionButton( onPressed: colorManager.incrementRed, tooltip: 'Red', child: Text("R"), ), SizedBox(width: 10), FloatingActionButton( onPressed: colorManager.incrementGreen, tooltip: 'Green', child: Text("G"), ), SizedBox(width: 10), FloatingActionButton( onPressed: colorManager.incrementBlue, tooltip: 'Blue', child: Text("B"), ) ], ), ); } }
now inside the HomePage tree widget, we can easily access our object using two ways. Either we can use Provider.of<Object>(context) or Consumer Widget.

4. After that create color_manager.dart class and extend with
 ChangeNotifier. As you’ve probably must have guessed, all it does is add listening capability to our class. When we call any method(incrementRed..) of this class. It'll notify the updated values to the widget that we have linked by using Provider.
color_manger.dart
import 'package:flutter/material.dart'; class ColorManager with ChangeNotifier { int _red; int _green; int _blue; ColorManager (this._red, this._green, this._blue);
  getRed() => _red; setRed(int red) => _red = red; getGreen() => _green; setGreen(int red) => _green = red; getBlue() => _blue; setBlue(int blue) => _blue = blue; void incrementRed() { _red = _red + 10; notifyListeners(); } void decrementRed() { _red = _red - 100; notifyListeners(); } void incrementGreen() { _green = _green + 10; notifyListeners(); } void decrementGreen() { _green = _green - 100; notifyListeners(); } void incrementBlue() { _blue = _blue + 10; notifyListeners(); } void decrementBlue() { _blue = _blue - 100; notifyListeners(); } }

If you have followed the article carefully, you can see the app running very smoothly as shown above and backgound color changes by clicking on red, green and blue color cobination. But if you are facing any problem, please feel free to ask from comments.

Share:

Get it on Google Play

React Native - Start Development with Typescript

React Native is a popular framework for building mobile apps for both Android and iOS. It allows developers to write JavaScript code that ca...