import 'dart:collection';
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// 一个通用的InheritedWidget,保存任需要跨组件共享的状态
class InheritedProvider<T> extends InheritedWidget {
//共享状态使用泛型
final T data;
InheritedProvider({@required this.data, Widget child}) : super(child: child);
@override
//在此简单返回true,则每次更新都会调用依赖其的子孙节点的`didChangeDependencies`。
bool updateShouldNotify(InheritedProvider<T> oldWidget) {
return true;
}
}
Type _typeOf<T>() => T;
class ChangeNotifierProvider<T extends ChangeNotifier> extends StatefulWidget {
final Widget child;
final T data;
ChangeNotifierProvider({
Key key,
this.data,
this.child,
});
//定义一个便捷方法,方便子树中的widget获取共享数据
static T of<T> (BuildContext context) {
final type = _typeOf<InheritedProvider<T>>();
//final provider = context.inheritFromWidgetOfExactType(type) as InheritedProvider<T>;
//final provider = context.dependOnInheritedWidgetOfExactType(aspect: type) as InheritedProvider<T>;
final provider = context.dependOnInheritedWidgetOfExactType<InheritedProvider<T>>();
print("商品的Model是:${(provider.data as CartModel).totalPrice}");
return provider.data;
}
@override
_ChangeNotifierProviderState<T> createState() {
return _ChangeNotifierProviderState<T>();
}
}
/*
* _ChangeNotifierProviderState 主要作用就是监听到共享状态(model)改变时重新构建Widget树
*
*/
class _ChangeNotifierProviderState<T extends ChangeNotifier> extends State<ChangeNotifierProvider<T>> {
///如果数据发生变化(model类调用了notifyListeners),重新构建InheritedProvider
//void update() => setState(() => {});
void update() {
//build方法会被执行
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,
);
}
}
/*
* 定义一个Item类,用于表示商品信息
*
*/
class Item {
//商品单价
double price;
// 商品份数
int count;
Item(this.price, this.count);
}
/*
* 定义一个保存购物车内商品数据的CartModel类
* CartModel即要跨组件共享的model类
*/
class CartModel extends ChangeNotifier {
//用于保存购物车中商品列表
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();
}
}
/*
* 构建示例页面类:ProviderRoute
*
*/
class ProviderRoute extends StatefulWidget {
@override
_ProviderRouteState createState() => _ProviderRouteState();
}
class _ProviderRouteState extends State<ProviderRoute> {
@override
Widget build(BuildContext context) {
return Center(
child:ChangeNotifierProvider<CartModel>(
data: CartModel(),
child: Builder(builder: (context) {
return Column(
children:<Widget>[
Text(""),
Text(""),
Text(""),
Text(""),
Builder(builder: (context) {
var cart = ChangeNotifierProvider.of<CartModel>(context);
return Text("总价: ${cart.totalPrice}");
}),
Builder(builder: (context) {
//在后面优化部分会用到
print("RaisedButton build");
return RaisedButton(
child: Text("添加商品"),
onPressed: (){
ChangeNotifierProvider.of<CartModel>(context).add(Item(20.0, 1));
},
);
}),
],
);
}),
),
);
}
}
效果图:
购物车价格显示
网友评论