首页 > 其他分享 >flutter状态管理案例

flutter状态管理案例

时间:2023-07-14 14:55:05浏览次数:52  
标签:状态 Widget counter BuildContext class 案例 context Provider flutter

 

FLUTTER项目中管理不同组件、不同页面之间共享的数据关系。当需要共享的数据关系达到几十上百个的时候,我们就很难保持清晰的数据流动方向和顺序了,导致应用内各种数据传递嵌套和回调满天飞。在这个时候,我们迫切需要一个解决方案,来帮助我们理清楚这些共享数据的关系,于是状态管理框架便应运而生。

 

下面来了解一下如何使用Provider进行状态管理,使用步骤如下:

1、首先安装Provider   flutter pub get

dependencies:
  flutter:
    sdk: flutter
  provider: 6.0  #provider依赖

 

2、将需要共享的状态进行封装 就是类封装

//定义需要共享的数据模型,通过混入ChangeNotifier管理听众
class CounterModel with ChangeNotifier {
  int _count = 0;
  //读方法
  int get counter => _count; 
  //写方法
  void increment() {
    _count++;
    notifyListeners();//通知听众刷新
  }
}

这个类需要混入ChangeNotifier。这个类能够帮助我们管理所有依赖资源封装类的听众。当资源封装类调用 notifyListeners 时,它会通知所有听众进行刷新。

3、将封装的状态放在组件最高层,因为 Provider 实际上是 InheritedWidget 的语法糖,所以通过 Provider 传递的数据从数据流动方向来看,是由父到子(或者反过来),所以一般就是把资源放到更高的层级。需要注意的是是如何放。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
     //通过Provider组件封装数据资源
    return ChangeNotifierProvider.value(
        value: CounterModel(),//需要共享的数据资源
        child: MaterialApp(
          home: FirstPage(),
        )
    );
  }
}

 

因为 provider 是一个 Widget。所以,我们直接在 MaterialApp 的外层使用 Provider 进行包装,就可以把数据资源依赖注入到应用中,这里需要注意的是,由于封装的数据资源不仅需要为子 Widget 提供读的能力,还要提供写的能力,因此我们需要使用 Provider 的升级版 ChangeNotifierProvider。而如果只需要为子 Widget 提供读能力,直接使用 Provider 即可。

4、在子组件中通过of方法获取属性与方法,部署状态。

//第一个页面,负责读数据
class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //取出资源
    final _counter = Provider.of<CounterModel>(context);
    return Scaffold(
      //展示资源中的数据
      body: Text('Counter: ${_counter.counter}'),
      //跳转到SecondPage
      floatingActionButton: FloatingActionButton(
        onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) => SecondPage()))
      ));
  }
}

//第二个页面,负责读写数据
class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //取出资源
    final _counter = Provider.of<CounterModel>(context);
    return Scaffold(
      //展示资源中的数据
      body: Text('Counter: ${_counter.counter}'),
      //用资源更新方法来设置按钮点击回调
      floatingActionButton:FloatingActionButton(
          onPressed: _counter.increment,
          child: Icon(Icons.add),
     ));
  }
}

 

另一个例子

 

import 'package:flutter/material.dart';

class Datashare extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      children: [App1(), App2()],
    );
  }
}

class App1 extends StatelessWidget {
  // 获取属性与方法

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 100,
      color: Colors.yellow,
      child: Text("111"),
    );
  }
}

class App2 extends StatelessWidget {
  // 获取属性与方法
  
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 100,
      height: 100,
      color: Colors.redAccent,
      child: FlatButton(child: Text("加一"),color: Colors.redAccent,onPressed: ()=>{

      })
    );
  }
}

 

改造成支持provider   的代码

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

// 封装状态:
class CountContainer with ChangeNotifier {
  int _count = 0;
  int get counter => _count;

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

// class Datashare extends StatelessWidget {
//   @override
//   Widget build(BuildContext context) {
//     return Row(
//       children: [App1(), App2()],
//     );
//   }
// }

// 将封装的装填放到顶层组件;

class Datashare extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider.value(
        value: CountContainer(),
        child: Row(
          children: [App1(), App2()],
        ));
  }
}

class App1 extends StatelessWidget {
  // 获取属性与方法

  @override
  Widget build(BuildContext context) {
    final _counter = Provider.of<CountContainer>(context);
    print(_counter);
    return Container(
      width: 100,
      height: 100,
      color: Colors.yellow,
      child: Text('${_counter._count}'),
    );
  }
}

class App2 extends StatelessWidget {
  // 获取属性与方法

  @override
  Widget build(BuildContext context) {
    final _counter = Provider.of<CountContainer>(context);
    return Container(
        width: 100,
        height: 100,
        color: Colors.redAccent,
        child: FlatButton(
            child: Text("加一"),
            color: Colors.redAccent,
            onPressed: () => {
                _counter.increment()
            }));
  }
}

 

 

5、多个状态 共享 

数据状态的共享。

此时我么需要MultiProvider,我们修改上面的代码,注入一个只读的数字,这个数字只做展示,局部代码如下

 

class Datashare extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(providers: [
      Provider.value(value: 30.0),
      ChangeNotifierProvider.value(
          value: CountContainer(),
          )
    ],
    child: Row(
            children: [App1(), App2()],
          ));
  }
}

class App1 extends StatelessWidget {
  // 获取属性与方法

  @override
  Widget build(BuildContext context) {
    final _counter = Provider.of<CountContainer>(context);
    final textSize = Provider.of<double>(context);
    print(_counter);
    return Container(
      width: 100,
      height: 100,
      color: Colors.yellow,
      child: Text('${_counter._count}----$textSize'),
    );
  }
}

 

标签:状态,Widget,counter,BuildContext,class,案例,context,Provider,flutter
From: https://www.cnblogs.com/hztech/p/17553706.html

相关文章

  • SVN状态说明
    1、svnstatus查看工作副本中目录与文件的状态命令格式:svn status[PATH](简写:svnst)打印工作拷贝中文件和目录的状态。svnst|grep^状态(获得某状态文件列表)svnst|grep-v^状态(也作svnst|grep^[^状态],过滤掉某状态得到其他状态文件列表)例:svnst|grep^M   (......
  • flutter provider create: (_) => xxxx(),
    Provider通常使用ChangeNotifierProvider配合ChangeNotifier一起来实现状态的管理与Widget的更新。ChangeNotifierProvider本质上其实就是Widget,它作为父节点Widget,可将数据共享给其所有子节点Widget使用或更新;创建model,继承ChangeNotifier,用来实现数据更新的通知并监听......
  • 河北永宁花苑小区主入口水景雕塑 不锈钢仿真孔雀雕塑 实景案例
    河北永宁花苑小区主入口水景雕塑不锈钢仿真孔雀雕塑实景案例......
  • 用户案例 | Apache DolphinScheduler 离线调度在自如多业务场景下的应用与实践
    用户案例|自如随着自如业务的快速发展,不断增长的调度任务和历史逾万的存量任务对平台稳定性提出了更高的要求。同时,众多非专业开发人员也需要一种更为“亲民”的调度平台使用体验。如何满足这些日渐凸显的需求对自如大数据平台的开发团队来说,无疑是巨大的挑战。团队经过深入......
  • day118 - 基于xml管理bean的入门案例
    基于xml管理bean入门案例导入依赖<dependencies><!--基于Maven依赖传递性,导入spring-context依赖即可导入当前所需所有jar包--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId>......
  • SpringMVC入门案例
                ......
  • Flutter系列文章-Flutter环境搭建和Dart基础
    Flutter是Google推出的一个开源的、高性能的移动应用开发框架,可以用一套代码库开发Android和iOS应用。Dart则是Flutter所使用的编程语言。让我们来看看如何搭建Flutter开发环境,并了解Dart语言的基础知识。一、Flutter环境搭建1.安装FlutterSDK首先,访问Flutter官网下载Flutte......
  • react-d3-tree自定义节点使用案例
    react-d3-tree主要API及其中文解释:Tree组件的props:这些API提供了丰富的配置选项,可以用来定制树的外观和行为。例如,可以使用nodeSize属性调整节点的大小,使用pathFunc属性绘制自定义的连线,使用onClick属性处理节点的点击事件等等。data:树的数据对象。zoomable:指......
  • 直播软件源码,Flutter中导航栏和状态栏设置成透明
    直播软件源码,Flutter中导航栏和状态栏设置成透明一、Flutter透明状态栏设置 import'package:flutter/material.dart';//导入对应的文件import'package:flutter/services.dart';   voidmain(){ //配置透明的状态栏 SystemUiOverlayStylesystemUiOverlayStyle=co......
  • R语言线性混合效应模型(固定效应&随机效应)和交互可视化3案例|附代码数据
    全文下载链接:http://tecdat.cn/?p=23050最近我们被客户要求撰写关于线性混合效应模型的研究报告,包括一些图形和统计输出。在本文中,我们将用R语言对数据进行线性混合效应模型的拟合,然后可视化你的结果线性混合效应模型是在有随机效应时使用的,随机效应发生在对随机抽样的单位进行......