介绍
Provider
是一个由社区构建的状态治理包,而不是 Google
推出,但 Provider
是Google
极力推荐的状态治理形式之一,它是对 InheritedWidget
组件进行了封装,使其更易用,更易复用。
学习本章节前,心愿你能理解如下常识:
- 相熟 dart 语言
- 相熟 flutter 根本组件
- 理解 InheritedWidget
- 理解 ChangeNotifier
如果大家大家之前没接触过InheritedWidget
,那么倡议你先去理解,你能够通过链接来查看并把握对应的只是 英文官网文档 中文官网文档 源码剖析 视频教程
视频教程地址
视频教程地址
Provider 劣势
咱们为什么要用 Provider
而不是间接应用InheritedWidget
,咱们看下官网介绍
- 简化的资源分配与处理
- 懒加载
- 创立新类时缩小大量的模板代码
- 反对 DevTools
- 更通用的调用 InheritedWidget 的形式(参考 Provider.of/Consumer/Selector)
- 晋升类的可扩展性,整体的监听架构工夫复杂度以指数级增长(如 ChangeNotifier,其复杂度为 O(N))
Provider 类结构图
Provider 类阐明
Nested 组件
- Nested: 简化树结构嵌套过深
- SingleChildWidget: 单个子组件的组件,然而它与
ProxyWidget
不同,有一个build
办法。 - SingleChildStatelessWidget: 它是一个实现
SingleChildWidget
的StatelessWidget
,必须应用buildWithChild
构建子组件 - SingleChildStatefulWidget: 它是一个实现
SingleChildWidget
的StatefulWidget
,是与Nested
兼容的StatefulWidget
Provider 组件
Provider
组件分为四大类,别离如下:
Nested 系列
MultiProvider: 次要作用是进步代码可读性和缩小反复代码,是将多个提供者合并成单个线性的组件提供者。
SingleChildStatefulWidget 系列
- Selector0: 它是 Selector 至 Selector6 的基类
- Selector1-6: 它们是将
Selector0
与Provider.of
联合应用的语法糖,继承自Selector0
SingleChildStatelessWidget 系列
- Consumer1-6: 消费者,只是调用了
Provider.of
,次要作用是从顶层获取Provider<T>
并将其值传递给了builder
。 - InheritedProvider:
InheritedWidget
的通用实现,并且所有的继承自该类的都能够通过Provider.of
来获取value
- DeferredInheritedProvider:
InheritedProvider
的子类,用于监听流或者接管一个Future
- StreamProvider: 监听流,并暴露出以后的最新值。
- FutureProvider: 接管一个
Future
,并在其进入complete
状态时更新依赖它的组件。 - ListenableProvider: 供可监听对象应用的非凡
provider
,ListenableProvider
会监听对象,并在监听器被调用时更新依赖此对象的widgets
。 - ChangeNotifierProvider: 为
ChangeNotifier
提供的ListenableProvider
标准,会在须要时主动调用ChangeNotifier.dispose
。 - ListenableProxyProvider0: 可见的代理提供者,次要是从其余提供者获取值。
- ListenableProxyProvider1-6: 它是
ListenableProvider
的一个变体,继承ListenableProxyProvider0
, 从其余提供者获取值 - ChangeNotifierProxyProvider0: 次要用于构建和同步
ChangeNotifier
的ChangeNotifierProvider
。 - Provider: 最根底的 provider 组成,接管一个任意值并裸露它。
- ProxyProvider0: 它公开的值会通过创立或更新构建,而后传递给
InheritedProvider
。 - ProxyProvider1-6:
ProxyProvider0
的语法糖。
InheritedContext 系列
- InheritedContext: 与
InheritedProvider
关联的BuildContext
,提供公开的值 - ReadContext: 公开读取办法
- SelectContext: 在 BuildContext 上增加一个抉择办法。
- WatchContext: 公开 watch 办法。
Provider 根本应用
第一步:增加依赖
本文中所有的代码都是根本空平安的,所有 dart sdk 版本为>=2.12.0 <3.0.0
,目前官网最新版本为^6.0.1
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
provider: ^6.0.1
第二步:定义须要共享的数据
咱们这里创立了一个类 CountNotifier
继承了 ChangeNotifier
,咱们这里的案例是以计数器为案例,所有咱们定义一个变量count
,以及一个扭转数值的increment
办法,当咱们调用 increment
后会对 count
进行 +1,最初调用 notifyListeners()
来更新数据,代码如下:
import 'package:flutter/material.dart';
class CountNotifier with ChangeNotifier {
int count = 0;
void increment() {
count++;
notifyListeners();}
}
第三步:在应用程序入口初始化
咱们在 MaterialApp
之前对定义的共享数据进行了初始化,代码如下:
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(),),
);
}
}
第四步:应用共享数据
咱们定义了一个 counter
变量来获取到共享的数据,更新数据的办法间接通过 counter.increment()
,获取数据的办法通过ounter.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
),
),
),
);
}
}
总结
以上是对 Provider
进行了介绍、劣势、类构造和阐明以及一个根本应用的例子,绝对于应用 InheritedWidget
来说,显然 Provider
应用起来更简略。然而从它的提供者、消费者这些类来看略微简单,前面的章节中咱们来讲讲这些类