前言

非常感谢Vadaski大佬为这篇文章提供了很多技术支持,写这篇文章也是为了让自己更好的理解flutter,为以后更加深入学习flutter打下基础,如果看完这篇文章你对Flutter感兴趣,还可以看看这篇文章,对于新手也是非常的友好。

Vadaski/One-Punch-Flutter: Flutter Book (github)

在学习flutter之前,以java为例,初学者需要知道什么是类,方法,需要知道java的特性:封装,继承,多态。虽然不需要在java上有很高的造诣,但是需要对编程语言有一个大致的理解。在flutter中将会采用Dart语言来进行编程, Dart在静态语法方面和Java非常相似,如类型定义、函数声明、泛型等,而在动态特性方面又和JavaScript很像,如函数式特性、异步支持等,如果你会一些Java和JavaScript的语言基础,那么将会非常容易上手。

目录

前言

一、什么是Widget?

二、Widget与Element

三、StatelessWidget

四、StatefulWidget

五、State

五、总结


一、什么是Widget?

在学习flutter前我们需要知道什么是Widget,这是flutter中非常重要的东西,在flutter中几乎所有的对象都是一个Widget,有一句话叫: 在Flutter 中 Everything is Widget。

这里我们举一个例子:

现在我们想象有一个app页面,这个app页面由文字,图片,按钮组成,这些文字,图片,按钮就是我们从一个空白的页面上添加上去的组件,我们可以把Widget理解成构筑我们app页面的组件,所以文字是Widget, 图片是Widget,按钮也是Widget。不仅如此,如果我们想让这些组件按照我们想要的方式进行布局,我们布局的组件比如row(行布局),column(列布局),这些布局的组件也是Widget。

 

二、WidgetElement

在Flutter中,Widget的功能是“描述一个UI元素的配置数据”,也就是说,Widget并不是显示在页面上的元素,它是去配置显示在页面上的元素。

那么Flutter中真正代表屏幕上显示元素的类其实是element,我们的Widget是给我们的element设置参数,配置数据的。

我们举一个例子,假设你面前有一个人,你需要描述他的外观,你可以说他戴眼镜,身高170cm,双眼皮等等,你可以通过多种特征来描述你面前的这个人,当然,也可以只描述他有双眼皮。

所以,一个Widget可以对应多个Element。

 

三、StatelessWidget

StatelessWidget它继承自Widget类,所以它也是一个Widget,它重写了createElement()方法。根据英文名Stateless,我们可以知道这个类是没有State这个东西的,具体这个东西是什么,我们待会儿会介绍。在StatelessWidget中,我们通常会将静态的页面(没有数据更新)在build方法中去添加我们的文字,按钮,图片等等这些Widget来进行布局。

 

四、StatefulWidget

和StatelessWidget一样,StatefulWidget也是继承自Widget类,并重写了createElement()方法,不同的是返回的Element 对象并不相同;另外StatefulWidget类中添加了一个新的接口createState()。我们不用太过于纠结,初学者只要知道它的本质也是Widget就可以了。只要是当前页面可以变化的,动态的(有数据更新的)这一类页面都会放在StatefulWidget中,但是我们不会将build方法放在StatefulWidget中,那么我们应该在哪里去添加文字,按钮,图片呢?

 

五、State

一个StatefulWidget类会对应一个State类,当一个Statefulwidget同时插入到widget树的多个位置时,Flutte就会调用createState()方法为每一个位置生成一个独立的State实例。State实例只会在第一次插入到树中时被创建,当在重新构建时,如果widget被修改了,Flutter会动态设置State.widget为新的widget实例。

如果没看懂,没关系,我给你举个例子,以我们创建flutter项目的demo为例,这是一个计数器,当我们点击按钮后,会在页面显示点击的次数,从0开始。当我们点击了一次过后,我们记录了这次点击,希望这次点击的结果在页面上显示,页面上显示的数字从根本来讲,它是一个文本,而我们的文本在flutter中又是一个Widget,我们希望这个Widget的数值发生改变,当State的build方法生成的新widget实例,State就会去找到我们最新的那个Widget的状态。

State类就是我们去绘制动态页面的关键,所以我们可以去写一个新的类去继承这个State类,我们的build方法也会写到State类里面。

为什么我们的build方法不放在StatefulWidget里面而是要放在State里面?

这主要是为了提高开发的灵活性。如果将build()方法在StatefulWidget中则会有两个问题:

1.状态访问不便

我们前面提到,我们会将动态的,有数据变化的页面放在StatefulWidget里面,但是储存我们状态的却是State类,我们在build方法中写好了很多Widget,当我们状态需要更新的时候就会调用build方法,如果我们把build方法放在StatefulWidget中,我们需要从StatefulWidget的隔壁State中读取状态,很不方便,所以干脆将build方法写在state类中

2.继承StatefulWidget不便

举个例子,Flutter中有一个动画widget的基类AnimatedWidget,它继承自StatefulWidget类。AnimatedWidget中引入了一个抽象方法build(BuildContext context),继承自AnimatedWidget的动画widget都要实现这个build方法,我们如果把build方法写在StatefulWidget中,当我们使用这个做动画的Widget时,在StatefulWidget中会出现两个build方法,这样就麻烦了。

继续说回来,我们的State找到了最新的那个Widget就结束了吗?其实并不是,现在我们的页面上依旧不会有任何变化,那是因为,我们的State虽然找到了最新的Widget,但是我们当前的页面却依旧停留在上一个Widget的时刻,那么我们怎么去刷新页面呢?其实很简单,我们只需要在State中调用setState()方法,就可以将页面刷新,让页面显示当前State所找到的这个Widget。

 

五、总结

这篇文章我希望对于新手而言,能够起到一定的帮助,例子不一定很恰当,原理讲得也不深,但是对于新手而言,一开始这样子理解可以有助于之后的学习,在学习到后期的时候再去看一些原理就会轻松很多。让我们一起进步,共勉!

更多推荐

新手入门需要知道的Flutter基础