Flutter学习笔记(一)

Flutter的官方文档提供了一个理念——“一切皆为Widget”

由此可以看得出来Widget在Flutter中的重要地位

1. Widget是什么?

Widget我们将其理解为组件,一个应用的界面往往都比较丰富,上面会有各式各样的组件,像图片、按钮、播放器这些都可以称为组件。

由于之前自己接触过React的开发,因此我认为,这里的组件就相当于程序中的一个对象,它具有专门的功能,与用户进行交互,处理相应的数据,就像你打开Material Design组件库一样,里面各个组件都扮演着特定的角色,为了某一种特定的功能而存在。

打个更加贴近生活的比方,我们刚搬进新家,而空荡荡的屋子就是我们原始的空白界面,然而我们的日常生活总是需要各种工具或者是家具来满足我们的需要,那么这种需要就相当于是组件所需要具备的功能,每个工具或者家具只是专门负责某一方面的功能,此时,在我看来,就可以将家具或工具理解为程序意义上的组件,同时,这些组件的摆放和搭配也形成了界面上丰富多彩的布局。

2. Widget有哪些?

  • 无状态组件(Stateless Widget)
  • 有状态组件(Stateful Widget)

可以将组件根据状态特点分为两个大类

2.1. 无状态组件

StatelessWidget类直接继承于Widget

无状态组件具体做些什么事呢?它的任务很简单,仅仅是将需要展示的内容进行呈现,而后就躺平了。

StatelessWidget是一个抽象类,需要重写抽象方法build()

1
2
3
4
5
6
7
8
9
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () => {},
child: const Text('Flutter')
,
);
}

简单使用一个TextButton的内置组件构成第一个无状态组件的内容,在build方法中返回需要展示的Widget对象

image-20220403171552181

2.2. 有状态组件

无状态组件似乎看起来挺简单的,接下来关注一下有状态组件,它能够实现组件状态的切换。

有状态组件需要继承自StatefulWidget类,另外,由于其需要对状态进行操作,还会涉及到State

首先,先定义一个继承于StatefulWidget类的组件,并且重写createState()方法

1
2
3
4
5
6
7
8
9
class AnotherWidget extends StatefulWidget {

String text = '空空如也';

@override
_AnotherWidgetState createState() {
return _AnotherWidgetState();
}
}

给出text作为一个组件的属性,用于显示文本

State类是一个抽象类,createState()需要返回一个状态,因此,专门为该组件设置一个状态类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class _AnotherWidgetState extends State<AnotherWidget> {

String textState = "";

// 初始化状态
@override
void initState() {
textState = widget.text;
}

// 自定义一个函数来更新状态
void _changeText(String s) {
setState(() {
textState = s;
});
}

@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () => _changeText('内有玄机'),
child: Text(textState)
);
}

}

这里定义该组件的状态,让其继承State类,使用泛型让它和对应的组件间建立联系

而后对应的泛型会被赋给State的成员widget上,通过该成员便可以获取之前定义的组件上的text属性

重写initState()方法对状态进行初始化的赋值操作,这里使用textState记录状态

setState()则是用来更新状态的,在这里就是将变量进行修改

build()就像之前无状态组件里的一样,用于呈现组件,利用其onPressed属性,监听点击,触发状态修改

image-20220403203721828image-20220403203810971

这样,通过对于变量textState的修改,更新了UI的文本显示

3. 几个重要的方法

3.1. setState()

在有状态组件中,通过数据的变更来触发UI的改变,setState()方法就是用来操作状态的,它所起到的作用就是触发组件树的重建,并且将新的状态数据更新到组件上

基于上面的代码,也就是说,按下按钮触发_changeText(String s)方法,从而调用内部的`setState() 通知关联的组件进行重建,以呈现新的状态

3.2. initState()

这是组件状态对象中第一个被调用的方法,正如其名字一样,主要进行一些状态初始化的操作,属于状态生命周期里的内容

3.3. dispose()

initState()相对应,在状态生命周期结束前调用,主要用于释放资源

3.4. build()

在无状态组件和有状态组件的状态类中都有它的踪影

组件通过组合往往会形成更加复杂的组件,将组件呈现出来的过程总是离不开“套娃”。其实这也是对应了组件树的概念

build()返回的Widget其实是最外层的组件,因为将里面的内容相当于打了个包,这样便将整个需要显示的内容都准备好了