First of all, of course, you can look at the official document translation reference
Why is Provider management state needed
Data changes, data sharing, need providers
- The code for Flutter, yes
Responsive/declarative
. The old Android /iOS code, yesimperative
. responsive
Code, basically all need to be carried outState management
It can also be understood thatData sharing
.The interface, the data is changing, it needs to be managed,
simpleIt is better to manage the widgets directly in the StatefulWidget, but more complicated to manage the widgets with providers and the like
.
Examples of simple and complex data
How simple is a change in the data? — Such as the current page in a PageView component, the current progress in a complex animation, the currently selected TAB in a BottomNavigationBar. These are in the widget tree, and other parts do not need to access this state. There is no need to serialize the state, and the state does not change in complex ways.
What data changes do Privider need to manage? For example, user options, login information, notifications in a social app, shopping cart in an e-commerce app, read/unread article status in a news app.
.
Flutter state management includes Redux, Rx, hooks, ScopedModel, and Provider, which is officially recommended.
If you don’t know anything else, it must be the official recommendation first.
Second, the use of Provider
Well, providers are officially recommended. Unfamiliar, can look at these two first.
Provider official article
Use a Provider to manage the status of the Flutter application
Ii.1 Operation Procedure
The introduction of the provider
dependencies:
provider: ^3.1. 0
Copy the code
There are three simple steps to using a provider:
- Create shared classes that inherit from ChangeNotifier
- Set up the data
- Get data in two ways: provider.of (context) and Consumer
Very simple ~
.
The simplest example isProvider.of (context)
The following code:
- Create a shared class, add a method that grows the data, and refresh on call
- Call the data
- Build is called again to refresh the UI
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:flutter/foundation.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Create widgets that hold CounterNotifier data
return ChangeNotifierProvider.value(
value: CounterNotifier(),
child: MaterialApp(
title: 'Privoder Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ProvidePage(title: 'Provider Test page '),),); }}class ProvidePage extends StatelessWidget {
final String title;
ProvidePage({Key key, this.title}) : super(key: key);
@override
Widget build(BuildContext context) {
// Get CounterNotifier data (the simplest way)
final counter = Provider.of<CounterNotifier>(context);
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Press the button to make the number grow :',
),
Text(
'${counter.count}',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
counter.increment();
},
tooltip: 'Increment',
child: constIcon(Icons.add), ), ); }}// Core: inherited from ChangeNotifier
// This type of file should be attached to a separate class file
class CounterNotifier with ChangeNotifier {
int _count = 0;
int get count => _count;
increment() {
_count++;
// The core method notifies the UI refresh and calls the build methodnotifyListeners(); }}Copy the code
.
Effect:
Pay attention to
- Using provider. of When notifyListeners are called in the ChangeNotifier, the build in the Widget is called again each time
That’s about it. You might say, well, setState. No, this is definitely different. SetState is so inflexible.
.
2.3 Example Consumer mode
Example: Set a value on page 1 and display it on page 2 (don’t ask why you don’t use Navigator directly, demo, just demo)
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
main() {
runApp(ChangeNotifierProvider<CounterNotifier>.value(
value: CounterNotifier(),
child: MyApp(),
));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MultiProvider(
providers: [
Provider.value(value: 36),
ChangeNotifierProvider.value(value: CounterNotifier())
],
child: MaterialApp(
title: 'Privoder Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: Page1(), ), ); }} class Page1 extends StatelessWidget {@override Widget Build (BuildContext Context) {// Get text size final size = Provider.of<int>(context).toDouble(); Final counter = Provider. Of <CounterNotifier>(context); // Output when calling buildprint('rebuild page 1');
return Scaffold(
appBar: AppBar(
title: Text('Page1'),), body: Center (child: the Column (mainAxisAlignment: mainAxisAlignment Center, children: < widgets > [/ / show the count Text ('Current count: ${counter.count}', // Set text size style: TextStyle(fontSize: size,), SizedBox(height: 50,), // jump Page2 RaisedButton(onPressed: () => Navigator.of(context).push( MaterialPageRoute(builder: (context) => Page2()), ), child: Text('Next'),),),),); } } class Page2 extends StatelessWidget { @override Widget build(BuildContext context) {print('rebuild page 2');
return Scaffold(
appBar: AppBar(
title: Text('Page2'),
),
body: Center(
child: Consumer2<CounterNotifier, int>(
builder: (context, counter, size, _) {
print('rebuild page 2 refresh count');
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'${counter.count}', style: TextStyle( fontSize: size.toDouble(), ), ), ], ); }),), floatingActionButton: floatingActionButton (onPressed: () {falseBuild) Provider. Of <CounterNotifier>(context, listen:false).increment();
},
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
class CounterNotifier with ChangeNotifier {
int _count = 0;
int get count => _count;
increment() { _count++; notifyListeners(); }}Copy the code
.
Pay attention to
- 1, Inside Page2, use Consumer
- If Provider. Of’s listen is false, build will not be called again
Set the value on page 2. When page 1 is returned, the value of page 2 is displayed on page 1
.
.
contrast
- Provider. Of: If you just need to get the data model,
You don't need to listen for changes
It is recommended to use Provider. Of (context, listen: false) to retrieve the data model. - Listener (Consumer recommended) : Consumer is recommended.
.
END
Reference: Flutter start dry series – State Management Provider3