Flutter 中是通过 Widget 嵌套 Widget 的方式来构建UI和进行事件处理的,所以记住,Flutter 中万物皆为Widget。
当 Widget 第一次插入到 Widget 树时会被调用,对于每一个State对象,Flutter 框架只会调用一次该回调,所以,通常在该回调中做一些一次性的操作,如状态初始化、订阅子树的事件通知等。不能在该回调中调用BuildContext.dependOnInheritedWidgetOfExactType(该方法用于在 Widget 树上获取离当前 Widget 最近的一个父级InheritedWidget,关于InheritedWidget我们稍后介绍,原因是在初始化完成后, Widget 树中的InheritFromWidget也可能会发生变化,所以正确的做法应该在在build()方法或didChangeDependencies()中调用它。
当State对象的依赖发生变化时会被调用;例如:在之前build() 中包含了一个InheritedWidget ,然后在之后的build() 中InheritedWidget发生了变化,那么此时InheritedWidget的子 Widget 的didChangeDependencies()回调都会被调用。典型的场景是当系统语言 Locale 或应用主题改变时,Flutter 框架会通知 Widget 调用此回调。需要注意,组件第一次被创建后挂载的时候(包括重创建)对应的didChangeDependencies也会被调用。
此回调读者现在应该已经相当熟悉了,它主要是用于构建 widget 子树的,会在如下场景被调用:
在调用initState()之后。
在调用didUpdateWidget()之后。
在调用setState()之后。
在调用didChangeDependencies()之后。
在State对象从树中一个位置移除后(会调用·deactivate·)又重新插入到树的其他位置之后。reassemble():此回调是专门为了开发调试而提供的,在热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用。
在 Widget 重新构建时,Flutter 框架会调用widget.canUpdate来检测 Widget 树中同一位置的新旧节点,然后决定是否需要更新,如果widget.canUpdate返回true则会调用此回调。正如之前所述,widget.canUpdate会在新旧 Widget 的 key 和 runtimeType 同时相等时会返回true,也就是说在在新旧 Widget 的key和runtimeType同时相等时didUpdateWidget()就会被调用。
当 State 对象从树中被移除时,会调用此回调。在一些场景下,Flutter 框架会将 State 对象重新插到树中,如包含此 State 对象的子树在树的一个位置移动到另一个位置时(可以通过GlobalKey 来实现)。如果移除后没有重新插入到树中则紧接着会调用dispose()方法。
当 State 对象从树中被永久移除时调用;通常在此回调中释放资源。

Flutter 提供了一套丰富、强大的基础组件,在基础组件库之上 Flutter 又提供了一套 Material 风格( Android 默认的视觉风格)和一套 Cupertino 风格(iOS视觉风格)的组件库。
基础组件库导入:
1 | import 'package:flutter/widgets.dart'; |
Material(安卓风格)组件,需要先引入它:
1 | import 'package:flutter/material.dart'; |
Cupertino(iOS风格)组件,需要先引入它:
1 | import 'package:flutter/cupertino.dart'; |
由于 Material 和 Cupertino 都是在基础组件库之上的,所以如果我们的应用中引入了这两者之一,则不需要再引入flutter/widgets.dart了,因为它们内部已经引入过了。
Flutter 的 Widget 类型分为StatefulWidget 和 StatelessWidget 两种,需要深入理解它们的区别,Widget 将是我们构建Flutter应用的基石。
响应式的编程框架中都会有一个永恒的主题——“状态(State)管理”,无论是在 React/Vue(两者都是支持响应式编程的 Web 开发框架)还是 Flutter 中,他们讨论的问题和解决的思想都是一致的。
管理状态的最常见的方法:
如何决定使用哪种管理方法?下面是官方给出的一些原则可以帮助你做决定:
InheritedWidget 是 Flutter 中非常重要的一个 Widget,它用于在 Widget 树中共享数据和状态。它提供了一种更高效的方式来将数据传递给子 Widget,避免直接将数据作为参数一层层传递。下面会详细介绍 InheritedWidget 的作用、用法、以及它的内部机制。
InheritedWidget 主要用于构建 Flutter 应用中的数据共享和状态管理。它的工作原理是通过一个继承自 InheritedWidget 的自定义 Widget,来封装需要共享的数据。然后,所有需要使用这些数据的子 Widget,可以通过 BuildContext 获取这个 InheritedWidget 中的数据。
Widget 树的上层放置数据源,树中需要访问数据的子 Widget 通过上下文进行访问。Widget 会被重新构建。这是一个必须实现的方法,用于确定当 InheritedWidget 更新时,是否需要通知其依赖的子 Widget。通常会比较新旧数据来决定是否需要更新:
1 |
|
这是一个常见的静态方法,用于在子 Widget 中获取 InheritedWidget。在实现中,通常会调用 BuildContext 的 dependOnInheritedWidgetOfExactType 方法:
1 | static MyInheritedWidget? of(BuildContext context) { |
Widget 使用,例如用户设置、主题、语言等。setState 重建,尤其在 Widget 树比较深时,可以大大提升性能。InheritedWidget 的工作原理主要基于 Flutter 框架的重建机制。当你调用 dependOnInheritedWidgetOfExactType 时,Flutter 会把当前 Widget 标记为依赖于某个特定的 InheritedWidget。如果该 InheritedWidget 发生变化(即 updateShouldNotify 返回 true),Flutter 将会触发依赖的 Widget 重新构建。
InheritedWidget 提供了一种高效且优雅的在 Widget 树中共享数据的方法,避免了直接将数据层层传递的复杂性。通过合理使用 InheritedWidget,可以显著减少不必要的重建,提升应用的性能。
Flutter非常流程新的框架 Provider 实际上是基于 InheritedWidget 进行封装的,是对它的一个高层抽象,目的是简化状态管理。