使用Provider对Flutter应用进行状态管理

Demo
创建共享数据类

import 'package:flutter/material.dart';
///数据 Model
/// Model 实际上就是我们的状态,
/// 它不仅储存了我们的数据模型,而且还包含了更改数据的方法,并暴露出它想要暴露出的数据。
/// ChangeNotifier这个类能够帮驻我们自动管理所有听众
/// 调用 notifyListeners() 时,它会通知所有听众进行刷新。
class Counter with ChangeNotifier {
  ///改变的变量
  int _value = 0;
 int get value =>_value;//将——value暴露出去
  ///增加逻辑
  add(){
    _value++;
    notifyListeners();//通知引用变量的地方改变值/// //父类的方法,发出通知
  }
  ///减少逻辑
  subtract(){
    _value--;
    notifyListeners();
  }
}

访问数据

Provider 获取数据状态有两种方式:
使用 Provider.of<T>(context)//导致调用的 context 页面范围的刷新
使用 Consumer//刷新了 Consumer 的部分
不过这两种方式都需要在顶层套上 ChangeNotifierProvider():
    
区别:
    Consumer 就是通过 Provider.of<T>(context) 来实现的
    实际上 Consumer 非常有用,它的经典之处在于能够在复杂项目中,极大地缩小你的控件刷新范围。
    Provider.of<T>(context) 将会把调用了该方法的 context 作为听众,并在 notifyListeners的时候通知其刷新。

使用Consumer -局部刷新而不是整个页面

直接用 Consumer 包住需要使用共享数据的 Widget,同样的,Consumer 也要指明类型。
建议各位尽量使用 Consumer 而不是 Provider.of<T>(context) 获取顶层数据
return Container(
  child: Consumer<Counter>(
    builder: (context, Counter counter, _) => 
    ///三个参数:(BuildContext context, T model, Widget child)
    ///context: context 就是 build 方法传进来的 BuildContext 在这里就不细说了
    ///T:获取到的最近一个祖先节点中的数据模型。
    ///child:它用来构建那些与 Model 无关的部分,在多次运行 builder 中,child 不会进行重建
    ///=>返回一个通过这三个参数映射的 Widget 用于构建自身
    Center(
       child: Column(
         children: <Widget>[
             Text(counter.value.toString()),
             RaisedButton(child: Text("增加"), onPressed: () => counter.add()),
             RaisedButton(child: Text("减少"), onPressed: () => counter.subtract())
         ],
       )
     ),
  )
);
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var dataInfo = Provider.of<DataInfo>(context);
    return MaterialApp(
      home: MyHomePage(),
      theme: dataInfo.themeData,
    );
  }
}
通过Provider.of<DataInfo>(context) 获取 DataInfo 实例,需要在 of 函数后指明具体的数据类。然后就可以直接通过 getter 访问到 themeData 了

使用Multiprovider管理多个共享数据类
数据类

在应用顶层放置MultiProvider

var counter = Counter();///引用model类
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: counter)
      ],
      child:MyApp(),
    )
  );

关于原则
1.不要所有状态都放在全局,严格区分你的全局数据与局部数据,资源不用了就要释放!
2.尽量在 Model 中使用私有变量"_"
3.控制刷新范围:组合大于继承的特性随处可见。常见的 Widget 实际上都是由更小的 Widget 组合而成,直到基本组件为止。为了使我们的应用拥有更高的性能,控制 Widget 的刷新范围便显得至关重要。

相关问题
Provider是如何做到状态共享的
1.获取顶层数据
2.通知刷新:使用了 Listener 模式。Model 中维护了一堆听众,然后 notifiedListener 通知刷新。(空间换时间)

应该在哪里进行数据初始化
1.全局数据
当我们需要获取全局顶层数据并需要做一些会产生额外结果的时候,main 函数是一个很好的选择。
我们可以在 main 方法中创建 Model 并进行初始化的工作,这样就只会执行一次。
2.单页面
页面级别的 Model 数据都在页面顶层 Widget 创建并初始化即可。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 要达到阅读的所有目的,就必须在阅读不同书籍的时候,运用适当的不同速度。不是所有的书都可以用最快的速度来阅读。法国学...
    清水河104金红敏阅读 516评论 0 2
  • 已经超过一个月没有写文章了,原因无非就是工作太忙。最近终于恢复以前的节奏,任务开始正常了起来。忙里偷闲,写一写人们...
    nick_young阅读 353评论 0 2
  • 席慕蓉说:“我总是躲在梦与季节的深处,听花与黑夜唱尽梦魇,唱尽繁华,唱断所有记忆的来路”。心境本就是一个广泛词,虽...
    爱吃肉的瘦子oo阅读 1,566评论 0 5