Flutter 数据传递
创始人
2024-05-27 06:23:05
0

在应用开发过程中数据传递,flutter提供 InheritedWidget 以及多种 provider, 各有差异从从使用习惯上面 这边主要介绍以下两种:

  • InheritedWidget
  • provider   (ChangeNotifier)

 InheritedWidget:

提供一种 从上而下 的数据提供 (而且子节点需要  Widget 包裹); 且单向切记只能由上而下的刷新数据;不能做到 子节点  变数据 而刷新的情况!常用于 静态数据的存储;不会改变的常量保存; 或者子节点只作为 静态展示的数据,父节点提供元数据。子节点展示数据 不参与动态更新交互

 

效果如下:

脚本结构:

 inherited_datum.dart

import 'package:flutter/cupertino.dart';class InheritedDatum extends InheritedWidget {final int count;const InheritedDatum({Key? key, required child, required this.count}): super(key: key, child: child);static InheritedDatum? of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType();}///**子组件不能 通过调用该方法 实现子组件刷新updateCount(int count) {count = count;}@overridebool updateShouldNotify(covariant InheritedDatum oldWidget) {// TODO: implement updateShouldNotifyreturn oldWidget.count != count;}
}

widget_child0.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';import 'inherited_datum.dart';class WidgetChild0 extends StatelessWidget {const WidgetChild0({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Container(color: Colors.blue,height: 40,width: 80,child: Center(child: Text('${InheritedDatum.of(context)?.count}',style: TextStyle(color: Colors.white),),),);}
}

widget_child1.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';import 'inherited_datum.dart';class WidgetChild1 extends StatelessWidget {const WidgetChild1({Key? key}) : super(key: key);@overrideWidget build(BuildContext context) {return Container(color: Colors.blue,height: 40,width: 80,child: Center(child: Text('${InheritedDatum.of(context)?.count}',style: TextStyle(color: Colors.white),),),);}
}

入口:main.dart

@override
Widget build(BuildContext context) {return Scaffold(appBar: AppBar(// Here we take the value from the MyHomePage object that was created by// the App.build method, and use it to set our appbar title.title: Text(widget.title),),body: Center(child: InheritedDatum(count: _counter,child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround,// children: const [],children: const [WidgetChild0(), WidgetChild1()],),),),floatingActionButton: FloatingActionButton(onPressed: _incrementCounter,tooltip: 'Increment',child: const Icon(Icons.add),), // This trailing comma makes auto-formatting nicer for build methods.);
}

InheritedWidget   使用注意细节:

1. 必须是 子组件平行的都不行:

2. 子组件获取 InheritedWidget 中的数据 通过:

InheritedDatum.of(context)?.count

3. 子组件不能仅 通过调用 InheritedWidget 中的方便实现 子组件刷新

小结

        InheritedWidget 的适用场景:子组件共享 父组件中的数据;但不具备 修改更新 父组件中数据的 能力!下面介绍的 ChangeNotifier 则具备 上下 更新数据的能力

provider    数据传递

provider是基于InheritedWidget 的包装 ;为了在Provider中进行数据共享首先我们需要为其定义一个数据模型,为了能够订阅数据的状态通常会让这个数据模型来继承 ChangeNotifier,达到更新的目的; 使用前先导入provider: ^6.0.5

dependencies:flutter:sdk: flutterprovider: ^6.0.5

之前的总结: https://johns.blog.csdn.net/article/details/122139508

需要在父节点中使用以下 组件来完成 子组件的更新:按照自己 更新逻辑的 复杂度。按照实际需要选取适合的 模型

  • ChangeNotifierProvider
  • ProxyProvider
  • MultiProvider
  • Consumer

效果如下:

父组件 和 子组件都可以 实现对数据的更新

 

脚本结构:

counter.dart

import 'package:flutter/cupertino.dart';class Counter with ChangeNotifier {int _count = 0;int get count => _count;void increment() {_count++;notifyListeners();}void set(int count) {_count = count;notifyListeners();}
}

 widget_child0.dart

import 'package:untitled1/counter.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';class WidgetChild0 extends StatelessWidget {const WidgetChild0({Key? key}) : super(key: key);Widget build(BuildContext context) {return Container(color: Colors.blue,height: 40,width: 80,child: GestureDetector(behavior: HitTestBehavior.opaque,onTap: () {context.read().set(0);print('WidgetChild0');},child: Center(child: Text('${context.watch().count}',style: TextStyle(color: Colors.white),),),),);}
}

widget_child1.dart

import 'package:untitled1/counter.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';class WidgetChild1 extends StatelessWidget {const WidgetChild1({Key? key}) : super(key: key);Widget build(BuildContext context) {return Container(color: Colors.blue,height: 40,width: 80,child: GestureDetector(behavior: HitTestBehavior.opaque,onTap: () {context.read().set(1);print('WidgetChild1');},child: Center(child: Text('${context.watch().count}',style: TextStyle(color: Colors.white),),),),);}
}

main.dart

class MyApp extends StatelessWidget {const MyApp({super.key});// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: ChangeNotifierProvider(create: (_) => Counter(),child: const MyHomePage(title: 'Flutter Demo Home Page'),),//home: const MyHomePage(title: 'Flutter Demo Home Page'),);}
}
  Widget build(BuildContext context) {return Scaffold(appBar: AppBar(// Here we take the value from the MyHomePage object that was created by// the App.build method, and use it to set our appbar title.title: Text(widget.title),),body: Center(child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround,// children: const [],children: const [WidgetChild0(), WidgetChild1()],),),floatingActionButton: FloatingActionButton(onPressed: () {context.read().increment();},tooltip: 'Increment',child: const Icon(Icons.add),), // This trailing comma makes auto-formatting nicer for build methods.);}

provide   使用注意细节:

也是共享的数据需要放在 父节点中; 再共有的父节点中 都可以对 数据进行修改更新; 实现双向动态数据: 调用

notifyListeners

其中 MultiProvider,Consumer 适合多组 ChangeNotifier ;以实现解耦操作;基本用法和ChangeNotifierProvider 相同;详细可参考:https://johns.blog.csdn.net/article/details/122139508https://johns.blog.csdn.net/article/details/122139508

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...