Flutter 数据传递

news2024/10/1 19:20:22

在应用开发过程中数据传递,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<InheritedDatum>();
  }

  ///**子组件不能 通过调用该方法 实现子组件刷新
  updateCount(int count) {
    count = count;
  }

  @override
  bool updateShouldNotify(covariant InheritedDatum oldWidget) {
    // TODO: implement updateShouldNotify
    return 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);

  @override
  Widget 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);

  @override
  Widget 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: flutter

  provider: ^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<Counter>().set(0);
          print('WidgetChild0');
        },
        child: Center(
          child: Text(
            '${context.watch<Counter>().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<Counter>().set(1);
          print('WidgetChild1');
        },
        child: Center(
          child: Text(
            '${context.watch<Counter>().count}',
            style: TextStyle(color: Colors.white),
          ),
        ),
      ),
    );
  }
}

main.dart

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget 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<Counter>().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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/374570.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

线上研讨会报名 | Perforce、中手游、星思半导体专家邀您一起畅聊如何通过数字资产管理与版本控制赋能大规模研发

全球领先的数字资产管理与DevSecOps工具厂商Perforce联合中国授权合作伙伴龙智举办的Perforce on Tour网络研讨会将于2月28日下午2:00举行。 本次研讨会以“赋能‘大’研发&#xff0c;助力‘快’交付”为主题&#xff0c;龙智董事长何明、Perforce高级顾问Robert Cowham&…

SpringMVC的基础知识以及如何使用各注解

1.SpringMVC的概述 学习SpringMVC我们先来回顾下现在web程序是如何做的&#xff0c;咱们现在web程序大都基于三层架构来实现。 三层架构 浏览器发送一个请求给后端服务器&#xff0c;后端服务器现在是使用Servlet来接收请求和数据 如果所有的处理都交给Servlet来处理的话&am…

SpringBoot (一) 项目构建、配置读取、静态资源定义

哈喽&#xff0c;大家好&#xff0c;我是有勇气的牛排&#xff08;全网同名&#xff09;&#x1f42e; 有问题的小伙伴欢迎在文末评论&#xff0c;点赞、收藏是对我最大的支持&#xff01;&#xff01;&#xff01;。 前言 SpringBoot是基于Spring开发的开源项目&#xff0c…

Apache 深入优化

Apache 深入优化 &#x1f3c6;荣誉认证&#xff1a;51CTO博客专家博主、TOP红人、明日之星&#xff1b;阿里云开发者社区专家博主、技术博主、星级博主。 &#x1f4bb;微信公众号&#xff1a;微笑的段嘉许 &#x1f4cc;本文由微笑的段嘉许原创&#xff01; &#x1f389;欢迎…

史上最全的大数据开发八股文【自己的吐血总结】

自我介绍 我本硕都是双非计算机专业&#xff0c;从研一下开始学习大数据开发的相关知识&#xff0c;从找实习到秋招&#xff0c;我投递过100公司&#xff0c;拿到过10的offer&#xff0c;包括滴滴、字节、蚂蚁、携程、蔚来、去哪儿等大厂&#xff08;岗位都是大数据开发&#…

阶段八:服务框架高级(第四章:Redis多级缓存案例)

阶段八&#xff1a;服务框架高级&#xff08;第四章&#xff1a;Redis多级缓存案例&#xff09;Day-Redis多级缓存案例0.学习目标1.何为多级缓存2.JVM进程缓存2.1.导入案例2.2.初识Caffeine 【重要】2.3.实现JVM进程缓存 【重要】2.3.1.需求2.3.2.实现3.Lua语法入门 【重要】3.…

idea 配置快捷生成类和方法注释,验证通过

1 Live Templates里新建模板组 . File-->Settings-->Editor--> Live Templates 属于组名,这里我选择MyComment 2. 新建类注释模板 2.1 选择上一步新建的模板组 2.2 编辑模板 (1)Abbreviation里输入想要的快捷键&#xff0c;这里我选择cl代表class; (2)Templates tex…

大数据之Phoenix基本介绍

文章目录前言一、Phoenix简介二、Phoenix入门&#xff08;一&#xff09;创建表语法&#xff08;二&#xff09;查看表信息&#xff08;三&#xff09;删除表&#xff08;四&#xff09;大小写问题前言 #博学谷IT学习技术支持# 上篇文章介绍了Phoenix环境搭建&#xff0c;点击…

IntelliJ插件开发教程之开发思路

JetBrains公司系列产品IDEA、WebStrom、PyCharm、CLion、GoLand等都是基于IntelliJ Platform开发而成&#xff0c;掌握IntelliJ插件开发技能便能拥有提升开发效率的终极武器。本教程Dmeo源码请关注微信公众号“开发效率”进行获取。如果您是JetBrains产品的用户&#xff0c;那您…

《C Primer Plus》第13章复习题与编程练习

《C Primer Plus》第13章复习题与编程练习复习题1. 下面的程序有什么问题&#xff1f;2. 下面的程序完成什么任务&#xff1f;&#xff08;假设在命令行环境中运行&#xff09;3. 假设程序中有下列语句&#xff1a;4. 编写一个程序&#xff0c;不接受任何命令行参数或接受一个命…

在Linux终端管理你的密码!

大家好&#xff0c;我是良许。 现在是互联网时代&#xff0c;我们每天都要跟各种 APP 、网站打交道&#xff0c;而这些东西基本上都需要注册才可以使用。 但是账号一多&#xff0c;我们自己都经常记不清对应的密码了。有些小伙伴就一把梭&#xff0c;所有的账号密码都是一样。…

计算机学生如何找到第一份实习?

作为一名计算机专业的学生&#xff0c;找到第一份实习是非常重要的一步&#xff0c;它不仅可以帮助你更好地了解行业&#xff0c;增加实践经验&#xff0c;还可以为即将到来的校招提供有力支持。计算机专业的校招&#xff0c;每年都在变得越来越卷。5年前&#xff0c;可能你只要…

android 加载隐私协议策略

背景&#xff1a;app各平台对隐私政策的监管越来越严格&#xff0c;app上线后&#xff0c;存在各种隐私协议的多次更新&#xff0c;每次更新都需要走发版流程&#xff0c;耗时耗力&#xff0c;为了解决这一问题&#xff0c;后端管理系统通过富文本 &#xff08;模板&#xff09…

数据结构与算法——2.算法概述

这篇文章&#xff0c;我们来讲一下算法的概述&#xff0c;大致理解一下什么是算法。 目录 1.定义 2.生活实例 3.算法目标 4.实际案例 4.1案例一 4.2案例二 5.小结 1.定义 官方解释&#xff1a; 算法是指解题方案的准确而完整的描述&#xff0c;是一系列解决问题的清…

前端面试题 —— 计算机网络(一)

目录 一、常见的HTTP请求头和响应头 二、HTTP状态码304是多好还是少好&#xff1f; 三、OPTIONS请求方法及使用场景 四、对keep-alive的理解 五、HTTP协议的优点和缺点 六、URL有哪些组成部分&#xff1f; 七、HTTPS通信&#xff08;握手&#xff09;过程 八、HTTPS的特…

浅析Windows Access Token以及利用方法

1 前置概念 关于Windows Access Token Windows Access Token(访问令牌)&#xff0c;它是一个描述进程或者线程安全上下文的一个对象。每个用户登录计算机都会产生一个AcessToken以用于创建进程和线程&#xff0c;用户注销以后会将主令牌切换成模拟令牌&#xff0c;也就是授权…

《网络安全入门到精通》 - 2.1 - Windows基础 - DOS命令Windows防火墙Windows共享文件

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「订阅专栏」&#xff1a;此文章已录入专栏《网络安全入门到精通》 Windows基础一、DOS命令1、目录文件操作dir 列出目录文件cd 切换目录md 创建目录rd 删除目录move 移动文件或目…

零入门kubernetes网络实战-18->命令行式操作tun设备介绍

《零入门kubernetes网络实战》视频专栏地址 https://www.ixigua.com/7193641905282875942 本篇文章视频地址(稍后上传) 1、如何操作tun设备呢&#xff1f; 主要提供两种形式&#xff1a; 命令行操作tun设备 openvpn(不介绍)tunctl(不介绍&#xff0c;不同系统间可能存在兼容…

第五章.最邻近规则分类(KNN)

第五章.最邻近规则分类&#xff08;KNN&#xff09; 5.1 最邻近规则分类&#xff08;KNN&#xff09; 1.KNN的计算方式 1).为了判断未知实例的类别&#xff0c;以所有已知类别的实例作为参照选择参数K。 2).计算未知实例与所有已知实例的距离 (利用欧氏距离公式) 其他距离衡量…

Nginx 原理

nginx是一个反向代理服务器&#xff0c;那么他是如何做到和服务器的连接呢&#xff0c;怎么进行负载均衡呢&#xff1f;如何支持高并发&#xff1f;&#xff1f;&#xff1f; Nginx的特点 &#xff08;1&#xff09;跨平台&#xff1a;Nginx 可以在大多数 Unix like OS编译运行…