Flutter Provider 异步通信、Provider状态管理

Flutter项目开发全套教程 专栏收录该内容
209 篇文章 150 订阅

题记
—— 执剑天涯,从你的点滴积累开始,所及之处,必精益求精。


Flutter是谷歌推出的最新的移动开发框架。

【x1】微信公众号的每日提醒 随时随记 每日积累 随心而过

【x2】各种系列的视频教程 免费开源 关注 你不会迷路

【x3】系列文章 百万 Demo 随时 复制粘贴 使用


在 Flutter 中可用于异步通信的方案有如下:


本文章实现的结果如下:
在这里插入图片描述


1 前言

Provider 很多网友会说用于状态管理,在这里小编称为异步通信。
Provider 是一个组件也是一种编程思想,在使用 Provider 时首先要添加依赖:点击查看最新版本

dependencies:
  provider: ^4.3.2+2

然后将依赖库拉取到本地

flutter packages get

provider 库中常用的组件有 ChangeNotifierProvider、MultiProvider、Provider、Consumer、Consumer2等等,后面会一一分析使用。

2 provider 的基本使用

第一步
就是在Flutter应用程序中提供一个 Provider 生产者,应用程序的整体可以是一个 Provider ,局部功能块也可以是单独的一个Provider,在这里,小编直接在根视图处理提供 ChangeNotifierProvider,如下代码清单1-1所示。完整源码在这里

///代码清单 1-1 
///flutter应用程序中的入口函数
void main() => runApp(
      ChangeNotifierProvider(
        create: (BuildContext context) {
          return TimeCounterModel();
        },
        child: ProviderMainApp(),
      ),
    );

ChangeNotifierProvider 将数据事件处理源 TimeCounterModel 与 界面显示的UI结合在一起,TimeCounterModel 是我们自定义的ChangeNotifier,Widget页面负责发送事件与消费事件结果。

如一个网络请求,Widget页面发出网络请求的指令,具体的网络请求处理逻辑在 ChangeNotifier 中,然后处理好数据结果后再发送到 Widget 页面中通过 Consumer 将数据结果渲染显示在页面上。

在这里插入图片描述

第二步: TimeCounterModel 定义如下:


///代码清单1-2 
import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';

class TimeCounterModel with ChangeNotifier {
  
  String _formatTime="00:00:00";
  
  void getCurrentTime() {
    ///获取当前的时间
    DateTime dateTime= DateTime.now();
    ///格式化时间 import 'package:intl/intl.dart';
    ///需要添加 intl 依赖
    _formatTime = DateFormat("HH:mm:ss").format(dateTime);
    notifyListeners();//2
  }
  
  get formatTime => _formatTime;//3
}

第三步
然后在 ProviderMainApp (当然外面还需要有一些嵌套,可以查看完整源码)这个页面中 定义了一个计时器 Timer 用来实现页面的时间按秒更新数据。

///代码清单1-3
class _TestABPageState extends State {
  ///计时器
  Timer _timer;
  @override
  void initState() {
    super.initState();
    ///间隔1秒执行时间
    _timer = Timer.periodic(Duration(milliseconds: 1000), (timer) {
      ///发送事件
      Provider.of<TimeCounterModel>(context,listen: false).getCurrentTime(); //2
    });
  }

  @override
  void dispose() {
    super.dispose();
    ///取消计时器
    _timer.cancel();
  }
    @override
  Widget build(BuildContext context) {... ... }
  
}

在这里使用到了Provider发送数据,其实就是通过 Provider 结合 context 来获取TimeCounterModel的过程,获取到 TimeCounterModel 再调用其 getCurrentTime方法获取当前时间来触发时间更新。

TimeCounterModel model = Provider.of<TimeCounterModel>(context,listen: false)

然后就是 build 方法中定义的消费者,代码如下:

 ///代码清单1-4
 /// 通过 Consumer 来消费事件结果
 Widget buildBlocBuilder() {
   return Consumer<TimeCounterModel>(
     ///参数 value 就是绑定的事件结果 TimeCounterModel
     builder: (BuildContext context, value, Widget child) {
       return Container(
         ///外边距
         margin: EdgeInsets.only(left: 12, top: 12),
         child: Text(
           '${value.formatTime}',
           style: TextStyle(fontSize: 22.0, color: Colors.red),
         ),
       );
     },
   );
 }

运行调试结果如下:
在这里插入图片描述

3 多数据源的巧妙操作

多数据源对应多个 ChangeNotifierProvider ,一个 Widget 页面同时需要绑定多个数据源的更新操作,每一个数据源都对应一个 ChangeNotifierProvider,在provider 框架中 通过 MultiProvider 来组合这些 ChangeNotifierProvider 代码如下:完整源码在这里

///代码清单2-1 
class TestProviderMulPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    ///组合多个Provider
    return MultiProvider(
      providers: [
        ///计时器
        ChangeNotifierProvider(
          create: (BuildContext context) {
            return TimeCounterModel();
          },
        ),
        ///随机数据
        ChangeNotifierProvider(
          create: (BuildContext context) {
            return RandomNumberModel();
          },
        )
      ],
      child: MaterialApp(
        home: TestConsumerTimePage(),
      ),
    );
  }
}

然后在事件消费结果处理处可以分别使用 Consumer 来处理结果,代码如下:

 @override
 Widget build(BuildContext context) {
   ///页面主体脚手架
   return Scaffold(
     appBar: AppBar(
       title: Text("Provider "),
     ),
     body: Column(
       children: [
         buildTimeConsumer(),
         buildNumberConsumer(),
       ],
     ),
   );
 }

/// 通过 Consumer 来消费事件结果
 /// 计时器的更新
 Widget buildTimeConsumer() {
   return Consumer<TimeCounterModel>(
     builder: (BuildContext context, value, Widget child) {
       return Container(
         ///外边距
         margin: EdgeInsets.only(left: 12, top: 12),
         child: Text(
           '当前时间 ${value.formatTime}',
           style: TextStyle(fontSize: 22.0, color: Colors.red),
         ),
       );
     },
   );
 }
 ///随机数的更新
 Widget buildNumberConsumer() {
   return Consumer<RandomNumberModel>(
     builder: (BuildContext context, value, Widget child) {
       return Container(
         ///外边距
         margin: EdgeInsets.only(left: 12, top: 12),
         child: Text(
           '回传的数据 ${value.randomNumber}',
           style: TextStyle(fontSize: 22.0, color: Colors.red),
         ),
       );
     },
   );
 }

运行效果如下:
在这里插入图片描述

当然也可以通过 Consumer2 来组合同时监听这两个结果代码如下:完整源码在这里

///通过 Consumer2 来同时监听处理两个结果
 Widget buildTimeConsumer2() {
   return Consumer2<TimeCounterModel,RandomNumberModel>(
     ///参数 value 为 TimeCounterModel 类型
     ///参数 value2 为 RandomNumberModel 类型
     builder: (BuildContext context, value,value2, Widget child) {
       return Container(
         ///外边距
         margin: EdgeInsets.only(left: 12, top: 12),
         child: Text(
           '当前时间 ${value.formatTime} 随机数 ${value2.randomNumber}',
           style: TextStyle(fontSize: 22.0, color: Colors.red),
         ),
       );
     },
   );
 }

运行调试效果如下:
在这里插入图片描述


以小编的性格,要实现百万Demo随时复制粘贴肯定是需要源码的

MultiProvider 、Consumer2 完整源码在这里

ChangeNotifierProvider 、Consumer 完整源码在这里

当然以小编的性格,肯定是要有视频录制的,目前正在录制中,你可以关注一下 西瓜视频 — 早起的年轻人 随后会上传

  • 5
    点赞
  • 0
    评论
  • 5
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

<p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">本系列课程讲解 Flutter 开发中,Provider 、Getx 、Bloc 、Stream 的基本使用与源码分析</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">Provider 是一由社区团队开发,谷歌开发者合作完善,Provider可以简单理解为跨组件通信,但实际上也是一种封装模式,本课程将从Provider的最基础使用出发,然后到最终的一个商品列表中添加购物车的功能。</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;"> </span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">主体内容分为以下几点 :</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">1 Provider 的基本使用,ChangeNotifier、ChangeNotifierProvider、的结合实现计数的修改功能。</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">2 Provider 中获取显示数据的三种方式,以及 Provider 通信原理</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">4  TabBar实现的分类标签,通过 Provider 进行数据交互 </span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">5  TabBarView 实现的标签页面,TabBarView与TabBar联动</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">6  TabBarView 标签页面中,ListView构建的列表页面,以及ListView数据绑定</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">7  ListView中 点击添加购物车的功能以及解决添加购物车全局刷新问题</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">8 Gextx 的路由管理</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">9 GetX 的局部更新</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">10  GetX 的基本使用 计数案例</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">11 GetX 响应式编程</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">12 搜索框的实时搜索</span></span></p> <p><span style="color: #666666; font-family: 微软雅黑;"><span style="font-size: 14px;">13 GetX 商品列表页面实现添加购物车功能</span></span></p>
参与评论 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:代码科技 设计师:Amelia_0503 返回首页

打赏作者

早起的年轻人

创作源于分享

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值