参考学习官网:《Flutter实战·第二版》
学习前先记住:Flutter 中万物皆为Widget,心中默念3次以上铭记于心。
这一点和开发语言Dart的变量一切皆是对象的概念,相互对应。
在前面的介绍中,我们知道在Flutter中几乎所有的对象都是一个 widget 。与原生开发中“控件”不同的是,Flutter 中的 widget 的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的 GestureDetector
、用于APP主题数据传递的 Theme
等等,而原生开发中的控件通常只是指UI元素。在后面的内容中,我们在描述UI元素时可能会用到“控件”、“组件”这样的概念,读者心里需要知道他们就是 widget ,只是在不同场景的不同表述而已。
Flutter 主要核心就是用于构建用户界面,说白了它做的界面可以跨平台,就只做界面,大部分开发认为 widget 就是一个控件,不必纠结于概念。
build
时复用旧的 widget (决定的条件在canUpdate()
方法中)Element(
在我们开发过程中基本不会调用到)
先看示意图:
最后一棵树是渲染树在上屏前会生成的 Layer 树,暂时不做讨论
它继承自widget类,重写了createElement()方法
@override
StatelessElement createElement() => StatelessElement(this);
StatelessElement 间接继承自Element类,与StatelessWidget相对应(作为其配置数据)。
StatelessElement用于不需要维护状态的场景,它通常在build方法中通过嵌套其他 widget 来构建UI,在构建过程中会递归的构建其嵌套的 widget 。
和StatelessWidget一样,StatefulWidget也是继承自widget类,并重写了createElement()方法,不同的是返回的Element 对象并不相同;另外StatefulWidget类中添加了一个新的接口createState()。
StatefulWidget的类定义:
abstract class StatefulWidget extends Widget {const StatefulWidget({ Key key }) : super(key: key);@overrideStatefulElement createElement() => StatefulElement(this);@protectedState createState();
}
StatefulElement 间接继承自Element类,与StatefulWidget相对应(作为其配置数据)。StatefulElement中可能会多次调用createState()来创建状态(State)对象。
createState() 用于创建和 StatefulWidget 相关的状态,它在StatefulWidget 的生命周期中可能会被多次调用。
StatelessWidget 和 StatefulWidget 都是用于组合其他组件的,它们本身没有对应的 RenderObject。
StatelessWidget:无状态使用;
StatefulWidget:有状态,且可变时使用;
StatelessWidget和StatefulWidget一定要记住写UI经常用到。
一个 StatefulWidget 类会对应一个 State 类,State表示与其对应的 StatefulWidget 要维护的状态,State 中的保存的状态信息允许:
State 中有两个常用属性:
- widget,它表示与该 State 实例关联的 widget 实例,由Flutter 框架动态设置。
- context,StatefulWidget对应的 BuildContext,作用同StatelessWidget 的BuildContext。
State生命周期 :看官方实例
initState:当 widget 第一次插入到 widget 树时会被调用,对于每一个State对象,Flutter 框架只会调用一次该回调。
didChangeDependencies :当State对象的依赖发生变化时会被调用。
build:主要是用于构建 widget 子树。
didUpdateWidget:在 widget 重新构建时,Flutter 框架会调用widget.canUpdate来检测 widget 树中同一位置的新旧节点,然后决定是否需要更新,如果widget.canUpdate返回true则会调用此回调。
reassemble:热重载(hot reload)时会被调用,此回调在Release模式下永远不会被调用。
deactivate:State 对象从树中被移除时,会调用此回调。
dispose:当 State 对象从树中被永久移除时调用;通常在此回调中释放资源
由于 StatefulWidget 的的具体逻辑都在其 State 中,所以很多时候,我们需要获取 StatefulWidget 对应的State 对象来调用一些方法。
获取state对象的几种方法
- context对象的findAncestorStateOfType()方法;
- ScaffoldState _state = context.findAncestorStateOfType
()!; - 直接通过of静态方法来获取State对象:(ScaffoldState _state=Scaffold.of(context);)
- 通过GlobalKey
2. 通过GlobalKey来获取State对象//定义一个globalKey, 由于GlobalKey要保持全局唯一性,我们使用静态变量存储 static GlobalKey
_globalKey= GlobalKey(); ... Scaffold(key: _globalKey , //设置key... ) _globalKey.currentState.openDrawer()
注意:使用 GlobalKey 开销较大,如果有其他可选方案,应尽量避免使用它。另外,同一个 GlobalKey 在整个 widget 树中必须是唯一的,不能重复。