Flutter状态管理Provider,简单上手

2023-11-19

学习Flutter一段时间了,偶然看到大家都说状态管理,多数人都是用redux,对于一个Android开发人员来说之前根本没接触过,于是开始了解redux,之后又了解闲鱼推出的fish_redux,然后又看到Vadaski发表的一系列关于Flutter状态管理的文章,包括Scoped Model, Redux, BLoC,RxDart,provide(想了解的可以移步),看的是眼花缭乱。对于Redux,能看懂是怎么写的,但真要到应用的层面,感觉还是有些吃力,更不知道怎样维护好它,一时间也不知道用什么什么适合自己。后来又接触到google推荐的Provider,于是学习了下。接下来就用Provider来实现一个计数的例子。

第一步,添加Provider依赖

provider: ^2.0.1+1
复制代码

pub地址:pub.dev/packages/pr…

第二步,创建Model

import 'package:provider/provider.dart';
class Counter with ChangeNotifier {//1
  int _count;
  Counter(this._count);

  void add() {
    _count++;
    notifyListeners();//2
  }
  get count => _count;//3
}
复制代码

简单的一个Counter对象,里面只有一个字段_count

  1. 这里需要混入ChangeNotifier
  2. 写一个增加的方法,然后需要调用notifyListeners();这个方法是通知用到Counter对象的widget刷新用的。
  3. get方法

第三步,使用ChangeNotifierProvider

通常main()方法是这么写

main() {
  runApp(MyApp());
}
复制代码

我们要监听改变就要在MyApp()外面套一层,这个是全局的,于是如下

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

main() {
  runApp(ChangeNotifierProvider<Counter>.value(//1
    notifier: Counter(1),//2
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: "Provider",
      home: HomePage(),
    );
  }
}

复制代码
  1. ChangeNotifierProvider调用value()方法,里面传出notifierchild
  2. notifier设置了默认的Counter(1)

当然Provider不止提供了ChangeNotifierProvider,还有Provider,ListenableProvider,ValueListenableProvider,StreamProvider, 具体可以看wiki. 如果想管理多个对象可以用MultiProvider,如下

MultiProvider(
  providers: [
    Provider<User>.value(value: user),
    Provider<Goods>.value(value: goods),
    .....
  ],
  child: someWidget,
)
复制代码

第四步,使用Provider获取Counter的值

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
        actions: <Widget>[
          FlatButton(
            child: Text("下一页"),
            onPressed: () =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return SecondPage();
                })),
          ),
        ],
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),//1
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();//2
        },
        child: Icon(Icons.add),
      ),
    );
  }
}
复制代码
  1. Provider.of<Counter>(context).count获取_count的值,Provider.of<T>(context)相当于Provider去查找它管理的Counter(1)
  2. Provider.of<Counter>(context).add();调用Counter()中的add()方法

同样第二个页面也这样写,如下

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("SecondPage"),
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),//1
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();//2
        },
        child: Icon(Icons.add),
      ),
    );
  }
}
复制代码

这样,当每个页面都点击+号按钮时,_count便会+1,同时通知并更新到使用它的地方。

完整代码,copy后可直接运行

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

main() {
  runApp(ChangeNotifierProvider<Counter>.value(
    notifier: Counter(1),
    child: MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      title: "Provider",
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("Home"),
        actions: <Widget>[
          FlatButton(
            child: Text("下一页"),
            onPressed: () =>
                Navigator.push(context, MaterialPageRoute(builder: (context) {
                  return SecondPage();
                })),
          ),
        ],
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(Provider.of<String>(context)),
      ),
      body: Center(
        child: Text("${Provider.of<Counter>(context).count}"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<Counter>(context).add();
        },
        child: Icon(Icons.add),
      ),
    );
  }
}

class Counter with ChangeNotifier {

  int _count;

  Counter(this._count);

  void add() {
    _count++;
    notifyListeners();
  }

  get count => _count;
}
复制代码

总结

看了那么多状态管理的,个人感觉Provider还是属于简单易用的,并且是google推荐的。但感觉还需要成长,让大家认可。我这里只是一个简单的使用,有一些地方也没讲太清楚还请大家见谅,同时也希望和各位学习Flutter的同学互相交流进步。

转载于:https://juejin.im/post/5d01f7826fb9a07ee742d9c4

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter状态管理Provider,简单上手 的相关文章

  • Android Studio如何添加工程(project)为library(针对非gradle)

    这篇文章还是针对非gradle build的工程 gradle build有一些差别 在Eclipse要引用别的工程为本工程的library很简单 但是在Android Studio还是稍稍有点小复杂的 那如何引用别的工程为本工程的libr
  • 防止运营商劫持apk

    title 防止运营商劫持apk tags https upyun apk 运营商 劫持 categories 工作日志 date 2017 05 25 18 18 56 目前f6部分系统使用了upyun的服务 包含apk的下载和静态资源等
  • HackPorts – Mac OS X 渗透测试框架与工具

    HackPorts是一个OS X 下的一个渗透框架 HackPorts是一个 超级工程 充分利用现有的代码移植工作 安全专业人员现在可以使用数以百计的渗透工具在Mac系统中 而不需要虚拟机 工具列表 0trace 3proxy Air Au
  • 金三银四必备,全面总结 Kotlin 面试知识点

    作者 彭旭锐 前言 在 Android 面试中很重视基础知识的考察 其中语言基础主要包括 Java Kotlin C C 三种编程语言 在小彭面试的经验中 发现很多同学的 Kotlin 语言能力只是停留在一些非常入门的语法使用上 在这篇文章
  • 移动开发之我见--“Android开发生涯”

    纵观这几年的发展 移动手机的发展真是翻天覆地 前两年诺基亚一统天下 苹果颠覆了整个手机市场 安卓也分得了一杯羹 WindowPhone手机也纯纯欲动 Bada也抓紧推出自己的系统 360也要推出自己的手机系统 百度 腾讯纷拥而至 未来世界是
  • ubuntu软件更新源,更改,可提高更新的速度,移动端app开发

    6 安装系统更新 打开 系统 gt 系统管理 gt 更新管理器 安装更新 完成后若系统提示重新启动 请重新启动系统 如果你是校园网用户 请查看 Ubuntu11 04教育网源 下面是Ubuntu 11 04一些常见的源 Ubuntu官方源
  • Android 更新UI方法的深度解析

    1 Handler public class SecondActivity extends Activity private static final int MSG WHAT 101 TextView tv Button btn priv
  • GoogleCast 简介

    Google Cast Function 依赖com android support mediarouter v7com google android gms play services cast frameworkCast 过程1 fra
  • 热修复——Bugly让热修复变得如此简单

    一 简述 在上一篇 热修复 Tinker的集成与使用 中 根据Tinker官方Wiki集成了Tinker 但那仅仅只是本地集成 有一个重要的问题没有解决 那就是补丁从服务器下发到用户手机上 如果你团队中的后台开发人员实力够强 那么完全可以自
  • Android EventBus保姆级源码解析(一)注册方法register

    记得上次写EventBus还是在上次 一年前 哈哈 转眼间又是一年了 发现对于EventBus的源码细节有点模糊 挖个坑捋捋EventBus的源码 由于项目中使用且当前最新版本源码变化不大 本文贴出的源码基于EventBus3 0 0 关于
  • arcgis for android 学习 - (5) 在地图指定位置添加“标记“,并尝试选中它

    我做一个例子 1 首先显示一个地图 2 点击 添加要素 按钮后再次点击地图 将会在地图上添加 红色的位置标记 3 再次点击按钮后 这时 就可以点击刚刚添加的 红色的位置标记 就可以查看到 该标记关联到得属性值 布局
  • luaj使用 方法签名规则 Cocos2dxLuaJavaBridge

    function AndroidHandler getParamJson local args nil local ok ret luaj callStaticMethod className getParamJson args Ljava
  • SSHDroid(SSH Server for Android)通过PC或命令连接android

    1 下载berserker android apps sshdroid apk 如果你懒的下载 给我留言 我会发给你 2 安装到手机 显示如图 简单解释一下 一般android系统没有root权限 Wifi Connection 是你连接的
  • 制作一个“生日快乐”App,来自程序员的生日礼物~

    点击上方 码农的后花园 选择 星标 公众号 精选文章 第一时间送达 之前给大家制作了一个来自程序员的表白神器 本期带大家做一个 生日快乐 App 来自程序员的生日礼物 不要再说程序员不懂浪漫咯 往期精彩 Android App 开发的三种姿
  • 差分隐私简介

    要点 差分隐私可以通过向聚合查询结果添加随机化 噪声 来实现 以保护个人的条目 而不会显著改变查询结果 t t 差分隐私算法保证攻击者能获取的个人数据几乎和他们从没有这个人记录的数据集中能获取的相差无几 t t 最简单的算法之一是拉普拉斯机
  • iOS逆向工程之App脱壳

    本篇博客以微信为例 给微信脱壳 砸壳 在iOS逆向工程中是经常做的一件事情 因为从AppStore直接下载安装的App是加壳的 其实就是经过加密的 这个 砸壳 的过程就是一个解密的过程 未砸壳的App是无法在Class dump Hoppe
  • 阿里P7大牛亲自教你!妈妈再也不用担心我的面试,讲的明明白白!

    第一次观看我文章的朋友 可以关注 点赞 转发一下 每天分享各种干货技术和程序猿趣事 前言 随着移动终端的快速发展 Android开发人员也越来越多 Android开发市场也进入了一个饱和的状态 Android开发人员也面临着难找一份好工作的
  • android-smart-image-view源码分析,android性能优化推荐书

    三 源码分析 从github上clone该项目 可以看到整个项目的代码只包含7个Java源文件 同时 还可进行扩展 方便使用者根据实际图片的来源进行扩展 我们来看看Class逻辑图 上面有提到 SmartImageView继承自ImageV
  • 零基础入门 HTML 的 8 分钟极简教程

    在今天 前端工程师已经成为研发体系中的重要岗位之一 可是与此相对的是 极少大学的计算机专业愿意开设前端课 大部分前端工程师的知识 也都是在实践和工作中不断学习的 最近收到很多同学的后台留言 说希望多推出一些前端方向的教程 今天我们就带来一个
  • APK加壳原理简述

    先把核心原理记录一下 代码随后再补 PRE dex文件结构知识和加壳原理 先看下dex文件的基本结构 对于加壳主要关注3个关键字 1 checksum 文件校验码 使用alder32算法 校验文件除了maigc和checksum外余下的所有

随机推荐

  • 20-Docker-常用命令详解-docker attach

    常用命令详解 docker attach 前言 docker attach 语法格式 options 说明 使用示例 进入容器 和docker exec 的区别 前言 本篇来学习docker attach命令 docker attach 作
  • 解决 -bash: ifconfig: command not found 实测有效

    1 查看是否已经联网 输入ip addr 或 ip a 发现ens33 中不包含IP内容 2 修改配置步骤 1 输入 cd etc sysconfig network scripts 回车 找到ifcfg ens33 注意 cd后面有空格
  • 坐标系和投影 知识的内容介绍

    回想一下 接触遥感专业也有几个年头了 而现在越来越偏离遥感了 突然想着把自己脑中的遥感知识整理出来 首先想到的便是坐标系和投影 我想这个东西困扰着80 以上的测绘 遥感和GIS领域的从业人员吧 群里经常有人问 我自己曾经也很迷糊 什么大地坐
  • Java测试题_1

    单选题 1 class Base Base System out print Base public class Alpha extends Base public static void main String args new Alph
  • JavaScript 获取 input 输入框内容的方法

    在 JavaScript 中获取 input 输入框内容的方法有以下几种 使用 document getElementById 方法获取输入框元素 再通过 value 属性获取输入框内容 示例代码如下 var input document
  • 吴恩达老师深度学习视频课笔记:逻辑回归公式推导及C++实现

    逻辑回归 Logistic Regression 是一个二分分类算法 逻辑回归的目标是最小化其预测与训练数据之间的误差 为了训练逻辑回归模型中的参数w和b 需要定义一个成本函数 cost function 成本函数 cost functio
  • Golang匿名结构体的使用

    一 结构体基础 结构体 struct 将多个不同类型的字段集中组成一种复合类型 按声明时的字段顺序初始化 type user struct name string age byte user user Tom 2 定义匿名结构体时没有 ty
  • 编程TRICK

    一 20200729 1 image和annots的数据类型要统一 如image annots设为np float32 在具体函数中 输入和输出的数据类型要保持一致 中间具体应用再改变数据类型 2 仿射变换可以用PIL的transform
  • Flowable入门系列文章113 - 进程实例 02

    1 激活或暂停流程实例 PUT运行时 process instances processInstanceId 表1 激活或暂停流程实例 URL参数 参数 需要 值 描述 processInstanceId 是 串 激活 挂起的流程实例的ID
  • 4.bio、request和request_queue

    通常一个bio对应上层传递给块层的I O请求 每个bio结构体实例及其包含的bvec iter bio vec结构体实例描述了该I O请求的开始扇区 数据方向 读还是写 数据放入的页 其定义如代码清单13 3所示 struct bvec i
  • Redis 分布式锁实现

    原文地址 http blog csdn net zhu tianwei article details 44927331 Redis是一个key value存储系统 和Memcached类似 但是解决了断电后数据完全丢失的情况 而且她支持更
  • 英文版线性代数笔记1

    是一个给自己期中复习做的笔记 第二课 关于矩阵 mxn的矩阵 是m行n列 先行后列 如A2 1 就是3 单位矩阵 关于向量 向量 有序有限的一列数字 定义 了解列向量 横向量 零向量 向量可以是一组解 关于单位向量 只有一个1 其他都是0
  • VC文件扩展名一览表

    VC文件扩展名一览表 2003 12 7 23 05 34 阅读589次 APS 存放二进制资源的中间文件 VC把当前资源文件转换成二进制格式 并存放在APS文件中 以加快资源装载速度 BMP 位图资源文件 BSC 浏览信息文件 由浏览信息
  • 西门子S7通信

    1 总体结构 1 1 西门子通信场景 在讨论更多的技术细节之前 首先我想简单介绍一下西门子通信场景的基本情况 当我谈到 S7协议 时 我指的是以太网S7通信 主要用于将PLC连接到 I PC站 PG PC PLC通信 不要将此与西门子设备使
  • okhttp源码分析

    Okhttp介绍 由square公司贡献的一个处理网络请求的开源项目 是目前Android使用最广泛的网络框架 从Android4 4开始HttpURLConnection的底层实现采用的是okhttp 项目地址 https github
  • 消息服务器 ws 高并发,HServer-JAVA: 基于Netty做的一个WebServer,同时集成MVC等相关快速开发功能的高并发服务器,做一些简单的应用分分钟搞定,同时性能报表...

    以下注解基本模拟Spring的功能 Bean 将Bean对象加入IOC容器中比如 按默名字加入IOC容器 Bean class TestService 指定名字加入容器 装配的时候就只能通过名字装配了 Bean testService cl
  • Element 修改el-table自带样式

    1 修改el table选中当前行高亮的样式 deep el table body tr current row gt td background color fff important 2 修改el table当前行的hover样式 de
  • 视觉SLAM漫谈

    视觉SLAM漫谈 1 前言 开始做SLAM 机器人同时定位与建图 研究已经近一年了 从一年级开始对这个方向产生兴趣 到现在为止 也算是对这个领域有了大致的了解 然而越了解 越觉得这个方向难度很大 总体来讲有以下几个原因 入门资料很少 虽然国
  • 22黑马QT笔记之事件全总结

    22黑马QT笔记之事件全总结 1 每个控件重写过滤器 event函数 各个事件处理函数都一样 都是先类中声明 类外定义 2 每个控件都可以重写事件过滤器 但是他一般写在窗口 安装时参数要求继承QObject嘛 event函数和各个事件处理函
  • Flutter状态管理Provider,简单上手

    学习Flutter一段时间了 偶然看到大家都说状态管理 多数人都是用redux 对于一个Android开发人员来说之前根本没接触过 于是开始了解redux 之后又了解闲鱼推出的fish redux 然后又看到Vadaski发表的一系列关于F