美文网首页flutter
Provider_组件

Provider_组件

作者: 卢融霜 | 来源:发表于2021-07-08 09:39 被阅读0次

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

相关文章

网友评论

    本文标题:Provider_组件

    本文链接:https://www.haomeiwen.com/subject/jpqiultx.html