Flutter之跨组件状态共享(Provider)

Flutter是Google(全球顶级互联网科技公司)出品,后台够硬,毫无疑问Flutter即将或已经成为跨平台开发的主流,Flutter野心很大,不仅冲击着原生开发,而且很有可能会烧到Web前端。作为移动端开发者的你,如果不关注Flutter的话,实在说不过去啦!

Flutter跨组件状态共享(Provider)应用

一、效果图

界面初始化状态
在这里插入图片描述

分别点击两个按钮,数据会相应变化
在这里插入图片描述
2、Flutter中集Provider

在pubspec.yaml文件中添加Provider,当前版本1.1.0:

 provider: ^3.1.0

2、创建用户实体

商品实体

class Item {
  Item(this.price, this.count);
  double price; //商品单价
  int count; // 商品份数
}

创建CartModel用来管理商品数据

import 'package:flutter/material.dart';
import 'package:ydcflutter_app/common/test/Item.dart';

class CartModel extends ChangeNotifier {
  // 用于保存购物车中商品列表
  final List<Item> _items = [];
  // 购物车中商品的总价
  double get totalPrice =>
      _items.fold(0, (value, item) => value + item.count * item.price);

  // 将 [item] 添加到购物车。这是唯一一种能从外部改变购物车的方法。
  void add(Item item) {
    _items.add(item);
    // 通知监听器(订阅者),重新构建InheritedProvider, 更新状态。
    notifyListeners();
  }
  var name;

  CartModel(this.name);

  void setName(String name) {
    this.name = name;
    notifyListeners();
  }

  String get getName => this.name;

}

我们将要共享的状态放到一个 CartModel类中,然后让它继承自ChangeNotifier,这样当共享的状态改变时,我们只需要调用notifyListeners() 来通知订阅者,然后由订阅者来重新构建InheritedProvider,达到刷新页面的目的。

3、使用ChangeNotifierProvider绑定数据

import 'package:flutter/material.dart';
import 'package:ydcflutter_app/common/test/CartModel.dart';
import 'package:ydcflutter_app/common/test/Item.dart';
import 'package:provider/provider.dart';

class TestPage extends StatefulWidget {
  @override
  State createState() => new _TestPageState();
}

class _TestPageState extends State<TestPage> {

  BuildContext mContext;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold( body:Center(
      child: ChangeNotifierProvider<CartModel>.value(
        value: new CartModel("格子衬衫"),
        child: Builder(builder: (context) {
          return Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Builder(builder: (context) {
                var cart = Provider.of<CartModel>(context);
                return Text("商品名称: ${cart.name}");
              }),
              Builder(builder: (context) {
                var cart = Provider.of<CartModel>(context);
                return Text("总价: ${cart.totalPrice}");
              }),
              Builder(builder: (context) {
                print("RaisedButton build"); //在后面优化部分会用到
                return RaisedButton(
                  child: Text("添加商品"),
                  onPressed: () {
                    //给购物车中添加商品,添加后总价会更新
                    Provider.of<CartModel>(context).add(Item(10.0, 1));
                  },
                );
              }),
              Builder(builder: (context) {
                print("RaisedButton build"); //在后面优化部分会用到
                return RaisedButton(
                  child: Text("修改商品名称"),
                  onPressed: () {
                    //使用Provider修改商品名称
                    Provider.of<CartModel>(context).setName("修改为无用牌毛巾");
                  },
                );
              }),

            ],
          );
        }),
      ),
    ));
  }


  Widget dividerWidget = new Container(
    //margin: const EdgeInsets.only( left: 10.0,right: 10.0),
      child: new Padding(
          padding: const EdgeInsets.only(left: 0.0, right: 0.0),
          child:
          new Divider(height: 1.0, indent: 0.0, color: Color(0xFFe5e5e5))
      )

  );

  @override
  void dispose() {
    super.dispose();
  }
}


ChangeNotifierProvider调用value()方法,里面传出notifier(CartModel)和child,并初始化了默认数据。

4、使用Provider获取数据

 Builder(builder: (context) {
                var cart = Provider.of<CartModel>(context);
                return Text("商品名称: ${cart.name}");
              }),

5、使用Provider更新数据

   Builder(builder: (context) {
                print("RaisedButton build"); //在后面优化部分会用到
                return RaisedButton(
                  child: Text("添加商品"),
                  onPressed: () {
                    //给购物车中添加商品,添加后总价会更新
                    Provider.of<CartModel>(context).add(Item(10.0, 1));
                  },
                );
              }),
              Builder(builder: (context) {
                print("RaisedButton build"); //在后面优化部分会用到
                return RaisedButton(
                  child: Text("修改商品名称"),
                  onPressed: () {
                    //使用Provider修改商品名称
                    Provider.of<CartModel>(context).setName("修改为无用牌毛巾");
                  },
                );
              }),

通过调用 ChangeNotifier.notifyListeners 对 ChangeNotifier(CartModel) 进行监听,将其公开给它的子 Widget 并重建依赖项,从而刷新我们的UI。

以上已经完成单个页面状态的管理,如果你想实现跨组件,跨路由状态共享。你只要把ChangeNotifierProvider放在整个应用的Widget树的根上即可。
在这里插入图片描述
各个页面中直接这样使用即可。
在这里插入图片描述

Flutter商城项目实战:https://github.com/dechengyang/ydc_flutter_app

如果对你有帮助,随意赏我奶粉钱吧,多谢!

微信:
在这里插入图片描述
支付宝:
在这里插入图片描述

发布了53 篇原创文章 · 获赞 58 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/XiNanHeiShao/article/details/103166141