introduce
Provider is a community-built state management package, not introduced by Google. However, Provider is one of the highly recommended state management methods by Google. It encapsulates InheritedWidget components to make them easier to use and reuse.
Before you start this chapter, you should know the following:
- Familiar with DART language
- Familiarize yourself with the basic components of FLUTTER
- Understand InheritedWidget
- Understand ChangeNotifier
If you haven’t used InheritedWidget before, we recommend that you do. You can use the InheritedWidget link to view and follow the source code analysis video provided in the InheritedWidget
Video Tutorial Address
Video Tutorial Address
The Provider edge
Why do we use a Provider instead of using an InheritedWidget directly
- Simplified resource allocation and disposal
- Lazy loading
- Reduce a lot of template code when creating new classes
- Support DevTools
- A more general way of calling InheritedWidget (refer to the Provider. Of/Consumer/Selector)
- Improved class extensibility, the overall listening architecture time complexity increases exponentially (e.g. ChangeNotifier, O(N))
Provider class structure diagram
Provider class description
Nested components
- Nested: Simplified tree structures are deeply Nested
- SingleChildWidget:A component of a single subcomponent, but it is associated with
ProxyWidget
Different, there is onebuild
Methods. - SingleChildStatelessWidget:It’s an implementation
SingleChildWidget
theStatelessWidget
, must be usedbuildWithChild
Building child components - SingleChildStatefulWidget:It’s an implementation
SingleChildWidget
theStatefulWidget
, it is withNested
compatibleStatefulWidget
The Provider component
Provider components fall into four categories as follows:
Nested series
MultiProvider: Improves code readability and reduces code duplication by combining multiple providers into a single linear component provider.
SingleChildStatefulWidget series
- Selector0: This is the base class for Selector to Selector6
- Selector1-6:They are the
Selector0
withProvider.of
Combined use of grammar sugar, inherited fromSelector0
SingleChildStatelessWidget series
- Consumer1-6:The consumer, it’s just called
Provider.of
, the main function is to fetch from the top levelProvider<T>
And passed its value tobuilder
. - InheritedProvider:
InheritedWidget
, and all inheritors of the class can passProvider.of
In order to getvalue
- DeferredInheritedProvider:
InheritedProvider
Class to listen on a stream or receive oneFuture
- StreamProvider: Listens for streams and exposes the current and latest values.
- FutureProvider:To receive a
Future
And in its entrycomplete
State updates components that depend on it. - ListenableProvider:Special for use by the listener
provider
.ListenableProvider
Listens on the object and updates dependencies on the object when the listener is calledwidgets
. - ChangeNotifierProvider: 为
ChangeNotifier
To provide theListenableProvider
Specification, which is automatically called when neededChangeNotifier.dispose
. - ListenableProxyProvider0: visible proxy provider, mainly from other providers to obtain values.
- ListenableProxyProvider1-6:It is a
ListenableProvider
A variant of inheritanceListenableProxyProvider0
Get values from other providers - ChangeNotifierProxyProvider0:Mainly used for building and synchronization
ChangeNotifier
theChangeNotifierProvider
. - Provider: The most basic component of a Provider that accepts an arbitrary value and exposes it.
- ProxyProvider0:The values it exposes are built by creating or updating and then passed to
InheritedProvider
. - ProxyProvider1-6:
ProxyProvider0
Grammar sugar.
InheritedContext series
- InheritedContext: 与
InheritedProvider
The associatedBuildContext
To provide a public value - ReadContext: Exposes the read method
- SelectContext: Add a selection method to BuildContext.
- WatchContext: Exposes the watch method.
Basic Use of Provider
Step 1: Add dependencies
All of the code in this article is basically null-safe, and all dart SDK versions are >=2.12.0 <3.0.0, with the latest official release being ^6.0.1
environment:
sdk: "> = 2.12.0 < 3.0.0"
dependencies:
flutter:
sdk: flutter
provider: ^6.01.
Copy the code
Step 2: Define the data you want to share
Here we create a class called CountNotifier that inherits from ChangeNotifier. In our case, we use the counter as a case, so we define a variable called count and a increment method to change the value. Increment is used to change count by +1, and notifyListeners() are called to update the data.
import 'package:flutter/material.dart';
class CountNotifier with ChangeNotifier {
int count = 0;
voidincrement() { count++; notifyListeners(); }}Copy the code
Step 3: Initialize at the application portal
We initialized the shared data defined before the MaterialApp as follows:
import 'package:flutter/material.dart';
import 'package:flutter_provider_example/provider_count_example/count_notifier.dart';
import 'package:flutter_provider_example/provider_count_example/provider_count_example.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => CountNotifier(),
child: MaterialApp(
debugShowCheckedModeBanner: false, home: ProviderCountExample(), ), ); }}Copy the code
Step 4: Use shared data
Increment (); unter.count.tostring (); unter.count.tostring ()
import 'package:flutter/material.dart';
import 'package:flutter_provider_example/provider_count_example/count_notifier.dart';
import 'package:provider/provider.dart';
class ProviderCountExample extends StatefulWidget {
@override
_ProviderCountExampleState createState() => _ProviderCountExampleState();
}
class _ProviderCountExampleState extends State<ProviderCountExample> {
@override
Widget build(BuildContext context) {
final counter = Provider.of<CountNotifier>(context);
return Scaffold(
appBar: AppBar(
title: Text("InheritedWidget"),
),
floatingActionButton: FloatingActionButton(
onPressed: (){
counter.increment();
},
child: Icon(Icons.add),
),
body: Center(
child: Text(counter.count.toString(),
style: TextStyle(
color: Colors.red,
fontSize: 50),),),); }}Copy the code
conclusion
With an introduction, advantages, class structure and explanation, and a basic usage example, providers are obviously easier to use than using inheritedWidgets. But it’s a little more complicated in terms of its provider and consumer classes, which we’ll cover in a later section