flutter InheritedWidget使用方法总结

目录
  • 引言
    • didChangeDependencies
    • 如何使用?
  • 结论

引言

InheritedWidget,flutter中非常重要的一个功能组件。比如我们在应用的根 widget 中通过InheritedWidget共享了一个数据,那么我们便可以在任意子 widget 中来获取该共享的数据。

didChangeDependencies

说到 InheritedWidget ,我们不得不聊聊 state 对象中的 didChangeDependencies 方法。当子控件依赖使用了父控件中的 InheritedWidget,比如主题、locale(语言)等发生变化时,依赖其的子 widget 的didChangeDependencies方法将会被调用。

一般来说,子 widget 很少会重写此方法,因为在依赖改变后 framework 也都会调用build()方法。但是,如果你需要在依赖改变后执行一些昂贵的操作,比如网络请求,这时最好的方式就是在此方法中执行,这样可以避免每次build()都执行这些昂贵操作。

重点: 如子控件build 方法中没有使用 InheritedShareWidget 的数据,那么它的didChangeDependencies将不会被调用

如何使用?

我们简单用一个 count 自增的例子来记录 InheritedWidget 的使用:

  • 新建 InheritedShareWidget 继承 InheritedWidget 作为共享数据源,以其为父节点提供子节点数据
import 'package:flutter/material.dart';
class InheritedShareWidget extends InheritedWidget {
  //用于共享的数据
  final int data;
  InheritedShareWidget({this.data, Widget child}) : super(child: child);
  //定义便捷方法,方便子控件获取共享数据
  static InheritedShareWidget of(BuildContext context) {
    ///当子控件依赖使用了我们的数据源时,数据变动会触发子控件中的 didChangeDependencies 方法
    return context.dependOnInheritedWidgetOfExactType<InheritedShareWidget>();
    ///(前提:子控件使用了数据源)子控件中的 didChangeDependencies 方法不会被触发
    // return context.getElementForInheritedWidgetOfExactType<InheritedShareWidget>().widget;
  }
  @override
  bool updateShouldNotify(covariant InheritedShareWidget oldWidget) {
    //返回true时,才会通知子控件
    return oldWidget.data != this.data;
  }
}

注意:updateShouldNotify方法中,通知指的是通知子控件的didChangeDependencies 方法,前提是子控件使用dependOnInheritedWidgetOfExactType 的方式获取共享数据。

  • 子节点中如何获取共享数据?
class TestShareChildWidget extends StatefulWidget {
  const TestShareChildWidget({Key key}) : super(key: key);
  @override
  _TestShareChildWidgetState createState() => _TestShareChildWidgetState();
}
class _TestShareChildWidgetState extends State<TestShareChildWidget> {
  @override
  void didChangeDependencies() {
    ///如build 方法中没有使用 InheritedShareWidget 的数据,那么它的didChangeDependencies()将不会被调用
    super.didChangeDependencies();
    print("enter didChangeDependencies");
  }
  @override
  Widget build(BuildContext context) {
    print("enter child build");
    //获取Inherited的共享数据:
    final data = InheritedShareWidget.of(context).data.toString();
    return Text(data);
  }
}
  • 两者通过父子嵌套的关系联系在一起:
class _TestInheritedWidgetState extends State<TestInheritedWidget> {
  int count = 0;
  @override
  Widget build(BuildContext context) {
    return Center(
      child: InheritedShareWidget(
        data: count,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TestShareChildWidget(),
            RaisedButton(
                child: Text('add'),
                onPressed: () {
                  setState(() {
                    ++count;
                  });
                })
          ],
        ),
      ),
    );
  }
}

大家注意到,demo中操作++count时,使用了setState手动触发控件进行刷新。

结论

InheritedWidget只提供我们共享数据的能力,以及控制是否在 build 前触发didChangeDependencies 的能力。不会主动触发build方法,如果build没被触发,那么didChangeDependencies 也不会被触发。

号外扩展

InheritedWidget 数据共享能力不会受到 Navigator push 新页面的影响,与原生不一样,flutter的页面跳转不是管理一个堆栈,Navigator 本质上是使用 overlay 管理一个 stack widget,因此 InheritedWidget 基于父子关系管理的数据共享条件没有被打破

以上就是flutter InheritedWidget使用方法总结的详细内容,更多关于flutter InheritedWidget使用的资料请关注我们其它相关文章!

(0)

相关推荐

  • Flutter 状态管理scoped model源码解读

    目录 一.什么是 scoped_model 二.用法 三.实现原理 四.结束 一.什么是 scoped_model 本文主要从 scoped_model 的简单使用说起,然后再深入源码进行剖析(InheritedWidget.Listenable.AnimatedBuilder),不会探讨 Flutter 状态管理的优劣,单纯为了学习作者的设计思想. scoped_model 是一个第三方 Dart 库,可以让您轻松的将数据模型从父 Widget 传递到子 Widget.此外,它还会在模型更新时

  • 使用PlatformView将 Android 控件view制作成Flutter插件

    目录 引言 1. FlutterPlugin 创建 2. 创建 Android 控件 3. 注册 Android 控件 4. 封装 Android 层通信交互 ‘CustomViewController’ 代码说明 5. 在 flutter 中如何使用已注册的 Android 控件(view) 代码说明 如何使用这个View 6. 附上 example 完整代码 引言 小编最近在项目中实现相机识别人脸的功能,将 Android 封装的控件 view 进行中转,制作成 FlutterPlugin

  • flutter中如何使用和扩展ThemeData实现详解

    目录 前言 Theme 的基本使用方式 1. Theme 的注册 2. 读取 ThemeData 里的配置: 小技巧介绍 ThemeData 内置字段不够用,如何扩展? 如何实现一键换肤 1. 首先在 yaml 新增引入 provider 2. 创建主题枚举 3. ThemeData 进行一层封装处理 4. 创建一个主题管理类 ThemeConfig 5. 通过ThemeData进行读取保持统一 6. 基于 provider 的使用 7. 创建一个主题仓库,里面存放两套主题,用于演示 Demo

  • flutter Bloc 更新后事件同步与异步详解

    目录 前言 使用方式 Bloc 新形态用法 事件队列的阻塞属性? 前言 最近,小轰参与了公司 flutter 项目关于 Dart 2.0 的空安全升级工作.我们升级了所有依赖的三方库,其中就包括有 Bloc 库.作为一款使用率颇高的状态管理框架, Bloc 在版本迭代中进行了少许结构和细节的优化,下面是小轰对于 Bloc 新版本的使用总结. 使用方式 小轰使用的 Bloc 版本如下 flutter_bloc: ^7.3.1 通过最简单的例子来学习新知识 创建一个包含 加 减 操作的页面,使用 b

  • Flutter 绘制风车实现示例详解

    目录 前言展示 1. 风车 1 的绘制 2. 风车 2 的绘制 3. 旋转动画的处理 4. 旋转动画的圈数 前言展示 最近源码看得比较多,本文来画点东西调节下心情,本绘制已收录于 FlutterUnit 的绘制集录,本文源码可参见[windmill.dart] .绘制内容非常简单,如下所示,两个样式的小风车:通过这两个小例子,可以学到: 路径的使用 画板的旋转变换 动画曲线与 Tween 的使用 风车1 风车2 1. 风车 1 的绘制 第一个风车非常简单,由四个 半圆 组成,每个部分直接的关系是

  • Flutter改变状态变量是否必须写在setState回调详解

    正文 我们都知道 setState(VoidCallback fn) 是这样用的: setState(() { count++; }); 执行完后组件会重新 build(),就可以取到 count 的最新值了.但其实这样写也是一样的: count++; setState(() {}); 因为 setState() 最后会调用 markNeedsBuild(),Flutter 会调度使组件 rebuild,所以状态变量的改变不是必须写在 setState() 的回调里面,只需要最后执行一下 set

  • flutter InheritedWidget使用方法总结

    目录 引言 didChangeDependencies 如何使用? 结论 引言 InheritedWidget,flutter中非常重要的一个功能组件.比如我们在应用的根 widget 中通过InheritedWidget共享了一个数据,那么我们便可以在任意子 widget 中来获取该共享的数据. didChangeDependencies 说到 InheritedWidget ,我们不得不聊聊 state 对象中的 didChangeDependencies 方法.当子控件依赖使用了父控件中的

  • Flutter SystemChrome使用方法详解

    目录 引言 setPreferredOrientations 设置横屏或坚屏 setEnabledSystemUIMode 设置全屏显示 setSystemUIOverlayStyle 设置 overlay 样式, 全屏播放视频 setSystemUIChangeCallback AnnotatedRegion 引言 SystemChrome 控制操作系统图形界面的特定方面以及它如何与应用程序交互. 需要注意的是在使用的时候一定要保证先执行 WidgetsFlutterBinding.ensur

  • Flutter使用push pop方法及路由进行导航详解

    目录 正文 准备工作 第一种导航方式 第二种导航方式 正文 在 Web/Mobile 应用程序中,导航是一个很重要的特性,因为它允许你从一个页面跳转到另一个页面. 在 flutter 应用程序中,我们可以使用 push(), pop() 方法实现导航,或者编写我们自己的路由. 准备工作 我们假设 FirstScreen 和 SecondScreen 是两个不同的类,分别在各自的 FirstScreen.dart 和 SecondScreen.dart 文件内. FirstScreen.dart

  • Flutter实战之自定义日志打印组件详解

    在Flutter中,如果我们需要打印日志,如果不进行自定义,我们只能使用自带的 print() 或者 debugPrint() 方法进行打印,但是这两种打印,日志都是默认 Info 层级的日志,很不友好,所以如果需要日志打印层级分明,我们就需要自定义一个日志打印组件,以下就来介绍如何自定义日志打印组件. 如何让输出的日志层级分明? 换种方式想,如果我们能在Flutter代码中,能够调用到原始Android中的Log组件,岂不是就能解决日志打印问题? 如何进行关联 在Flutter中,可以使用 M

  • Flutter混合开发详解

    混合开发简介 使用Flutter从零开始开发App是一件轻松惬意的事情,但对于一些成熟的产品来说,完全摒弃原有App的历史沉淀,全面转向Flutter是不现实的.因此使用Flutter去统一Android.iOS技术栈,把它作为已有原生App的扩展能力,通过有序推进来提升移动终端的开发效率. 目前,想要在已有的原生App里嵌入一些Flutter页面主要有两种方案.一种是将原生工程作为Flutter工程的子工程,由Flutter进行统一管理,这种模式称为统一管理模式.另一种是将Flutter工程作

  • Flutter网络请求的3种简单实现方法

    概述: App几乎都离不开与服务器的交互,本文主要讲解了flutter网络请求三种方式 flutter自带的HttpClient. 第三方库http 和 第三方库Dio  的简单实现 GET 和 POST请求,本文是笔者学习Flutter网络模块知识总结,若有问题还望不腻赐教. 一.系统自带HttpClient 1.使用中温馨提示 1.1.导入库 import 'dart:io'; // 网络请求 import 'dart:convert'; // 数据解析 1.2.Uri的多种初始化方式 //

  • 用Flutter开发自定义Plugin的方法示例

    当你在开发flutter应用的时候,有时会需要调用native的api,往往遇到flutter并没有相应的package, 这时候flutter plugin就开始发挥作用了,这篇文章将会讲解开发一个简单flutter plugin的步骤和方法,好了,让我们开始动手吧. 1.在Android Studio 中创建一个Flutter Plugin 项目,如下图 上图中你能看到项目描述中写到,如果需要暴露Andorid或iOS的API给开发者时,选择"Plugin"项目类型. 这个项目我们

  • Flutter下载更新App的方法示例

    1. 说明 iOS 和Android 更新是完全不一样的. iOS 只能跳转到 AppStore,比较好实现 Android则需要下载apk包,由于Android机型较多,这里我们用 dart 连接第三方(这里)的原生 android 下载库. 更新界面和下载更新分开处理的. iOS 没得下载进度这一说,Android 则有. 2. 代码 2.1 iOS 直接采用url_launcher就可以了 if (Platform.isIOS) { final url = "https://itunes.

  • Flutter ListView 上拉加载更多下拉刷新功能实现方法

    先上图 下拉刷新 跟原生开发一样,下拉刷新在flutter里提供的有组件实现 RefreshIndicator 一直不明白为啥组件中都提供下拉刷新,但就是没有上拉加载!! 我这请求接口数据用的是 http 库,是个第三方的是需要安装的 https://pub.dev/packages/http 用法如下 class MyHomePage extends StatefulWidget { MyHomePage({Key key}) : super(key: key); @override MyHo

随机推荐