前言
在学习完Flutter的常用组件之后,我们对这些组件的使用都有了一定的了解。但是,只是了解还是不够的,因为我们的数据是动态的,具备交互性,界面上的展示会根据用户的操作产生变化。这个时候,就需要对Flutter的状态管理机制有一定的了解,我们先来看一张图:
Flutter一切皆是组件,而组件Widget主要被划分为StatelessWidget和StatefulWidget两大类,下面将分辨介绍一下两类组件。
Widget
我们使用Flutter开发过程中,会出现布局层级。不管这个界面是简单的,还是复杂的,都会有布局的嵌套层级,这样的布局我们称为Widget树,并且在Widget之间存在这“父子”关系。其实Widget只是起到“描述”的作用,真正在屏幕上显示给用户看的UI是Element,Widget只是描述了Element的数据配置,Widget树的层级展现形式如下:
如果一个Widget存在子Widget,那么上一层的Widget就是父Widget,父Widget里面的则是子Widget。在实际开发中,我们会遇到复杂的布局情况,这个时候,不妨记住这颗布局树,回想一下,就会清晰了。
Context
做过Java开发的,应该清楚这个Context,因为用的最多,就是上下文的意思。Context对应的是,构建Widget树结构中具体某一个Widget的位置引用,并且它被视为Widget一部分,而每个Context只对应一个Widget。如果一个Context对应的是父Widget A,则Widget A对应的Context也包含了子Widget的Context。通过Context可以遍历和查找当前Widget树,Context之间也是关联在一起的,它们组成一颗Context树。
StatelessWidget
StatelessWidget即无状态的Widget,它无法通过setState设置组件的状态,其写法通过继承StatelessWidget,然后重写build函数来实现。对于其内部属性,应该声明为final,以防止被意外改变,例如:
class MyStatelessWidget extends StatelessWidget{ MyStatelessWidget({ Key key; this.parameter, }):super(key:key); final parameter; @override Widget build(BuildContext context){ return new .... } }
上面的代码中parameter参数只能传递一次,之后就无法被修改了。它的生命周期非常简单,就两部:1.初始化,2.通过build进行渲染。
StatefulWidget
StatefulWidget是有状态的Widget。当我们创建一个StatefulWidget组件时,它同时也创建了一个State对象,并且StatefulWidget通过与State关联可以达到刷新UI的目的。我们看一下官方的一个图示:
和React/Vue中的Reactive思想相似,但是还是有区别的,StatefulWidget只需要调用setState(…)方法,而不需要调用类似Android里的textView.setText(…)方法。某些组件在其生命周期里,内部数据会发生变化,基于这种情况,我们应该考虑使用StatefulWidget。
StatefulWidget的组成
StatefulWidget由两部分组成,第一部分为主体部分,代码如下所示:
class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); }
在主体部分里Widget继承了StatefulWidget的内容。在主体部分中创建的变量是无法变更的,第二部分代码如下:
class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { .......... } }
MyHomePageState前面以""开头,证明这个类为私有,可以通过widget.{name of the variable}格式访问第一部分里定义的变量,比如widget.title。
State
State是对StatefulWidget的行为和布局的描述,和StatefulWidget存在一一对应的关系。有时候StatefulWidget的组件需要改变其界面的表现形式,这个时候就可以通过setState(…)来改变。Flutter为我们做的服务功能非常全面,改变的过程只需要由Framework层控制,从而达到更新UI的目的。