Provider的原理
案例:
import 'package:flutter/material.dart';
import 'package:flutter_app_demo/pages/Provider/CartModel.dart';
import 'ChangeNotifierProvider.dart';
import 'Consumer.dart';
import 'Item.dart';
class ProviderRoute extends StatefulWidget {
@override
_ProviderRouteState createState() => _ProviderRouteState();
}
class _ProviderRouteState extends State<ProviderRoute> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Provider"),
),
body: Center(
child: ChangeNotifierProvider<CartModel>(
data: CartModel(),
child: Builder(builder: (context) {
return Column(
children: [
Consumer<CartModel>(
builder: (context, cart) => Text("总价: ${cart.totalPrice}")),
Builder(builder: (context) {
print("RaisedButton build");
return RaisedButton(
child: Text("添加商品"),
onPressed: () {
ChangeNotifierProvider.of<CartModel>(context,
listen: false)
.add(Item(20.0, 1));
},
);
}),
],
);
}),
),
),
);
}
}
import 'dart:collection';
import 'package:flutter_app_demo/pages/Provider/ChangeNotifier.dart';
import 'Item.dart';
class CartModel extends ChangeNotifierL {
// 用于保存购物车中商品列表
final List<Item> _items = [];
// 禁止改变购物车里的商品信息
UnmodifiableListView<Item> get items => UnmodifiableListView(_items);
// 购物车中商品的总价
double get totalPrice =>
_items.fold(0, (value, item) => value + item.count * item.price);
// 将 [item] 添加到购物车。这是唯一一种能从外部改变购物车的方法。
void add(Item item) {
_items.add(item);
// 通知监听器(订阅者),重新构建InheritedProvider, 更新状态。
notifyListeners();
}
}
import 'package:flutter/widgets.dart';
import 'ChangeNotifier.dart';
import 'InheritedProvider.dart';
class ChangeNotifierProvider<T extends ChangeNotifierL> extends StatefulWidget {
ChangeNotifierProvider({
this.data,
this.child,
});
final Widget child;
final T data;
//添加一个listen参数,表示是否建立依赖关系
static T of<T>(BuildContext context, {bool listen = true}) {
final provider = listen
? context.dependOnInheritedWidgetOfExactType<InheritedProvider<T>>()
: context.getElementForInheritedWidgetOfExactType<InheritedProvider<T>>()?.widget
as InheritedProvider<T>;
return provider.data;
}
@override
_ChangeNotifierProviderState<T> createState() =>
_ChangeNotifierProviderState<T>();
}
class _ChangeNotifierProviderState<T extends ChangeNotifierL> extends State<ChangeNotifierProvider<T>> {
void update() {
//如果数据发生变化(model类调用了notifyListeners),重新构建InheritedProvider
setState(() => {});
}
@override
void didUpdateWidget(ChangeNotifierProvider<T> oldWidget) {
//当Provider更新时,如果新旧数据不"==",则解绑旧数据监听,同时添加新数据监听
if (widget.data != oldWidget.data) {
oldWidget.data.removeListener(update);
widget.data.addListener(update);
}
super.didUpdateWidget(oldWidget);
}
@override
void initState() {
// 给model添加监听器
widget.data.addListener(update);
super.initState();
}
@override
void dispose() {
// 移除model的监听器
widget.data.removeListener(update);
super.dispose();
}
@override
Widget build(BuildContext context) {
return InheritedProvider<T>(
data: widget.data,
child: widget.child,
);
}
}
// 这是一个便捷类,会获得当前context和指定数据类型的Provider
import 'package:flutter/widgets.dart';
import 'ChangeNotifierProvider.dart';
class Consumer<T> extends StatelessWidget {
Consumer({
Key key,
@required this.builder,
this.child,
}) : assert(builder != null),
super(key: key);
final Widget child;
final Widget Function(BuildContext context, T value) builder;
@override
Widget build(BuildContext context) {
return builder(
context,
ChangeNotifierProvider.of<T>(context), //自动获取Model
);
}
}
class Item {
Item(this.price, this.count);
double price; //商品单价
int count; // 商品份数
}
image.png
apk下载地址
https://www.pgyer.com/IUVS
网友评论