阿八博客
  • 100000+

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

Flutter(七)之有状态的StatefulWidget

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/jsh/2019/0924/115084.html
前言一:接下来一段时间我会陆续更新一些列Flutter文字教程

更新进度: 每周至少两篇;

更新地点: 首发于公众号,第二天更新于掘金、思否、开发者头条等地方;

更多交流: 可以添加我的微信 372623326,关注我的微博:coderwhy

希望大家可以 帮忙转发,点击在看,给我更多的创作动力

一. StatefulWidget

在开发中,某些Widget情况下我们展示的数据并不是一层不变的:

比如Flutter默认程序中的计数器案例,点击了+号按钮后,显示的数字需要+1;

比如在开发中,我们会进行下拉刷新、上拉加载更多,这时数据也会发生变化;

而StatelessWidget通常用来展示哪些数据固定不变的,如果数据会发生改变,我们使用StatefulWidget;

1.1. 认识StatefulWidget

1.1.1. StatefulWidget介绍

如果你有阅读过默认我们创建Flutter的示例程序,那么你会发现它创建的是一个StatefulWidget

为什么选择StatefulWidget呢?

因为在示例代码中,当我们点击按钮时,界面上显示的数据会发生改变;这时,我们需要一个变量来记录当前的状态,再把这个变量显示到某个Text Widget上;并且每次变量发生改变时,我们对应的Text上显示的内容也要发生改变;

但是有一个问题,我之前说过定义到Widget中的数据都是不可变的,必须定义为final,为什么呢?

这次因为Flutter在设计的时候就决定了一旦Widget中展示的数据发生变化,就重新构建整个Widget;下一个章节我会讲解Flutter的渲染原理,Flutter通过一些机制来限定定义到Widget中的成员变量必须是final的;

Flutter如何做到我们在开发中定义到Widget中的数据一定是final的呢?

我们来看一下Widget的源码:

结论: 定义到Widget中的数据一定是不可变的,需要使用final来修饰

1.1.2. 如何存储Widget状态?

既然Widget是不可变,那么StatefulWidget如何来存储可变的状态呢?

StatelessWidget无所谓,因为它里面的数据通常是直接定义玩后就不修改的
但StatefulWidget需要有状态(可以理解成变量)的改变,这如何做到呢?

Flutter将StatefulWidget设计成了两个类:

也就是你创建StatefulWidget时必须创建两个类:一个类继承自StatefulWidget,作为Widget树的一部分;一个类继承自State,用于记录StatefulWidget会变化的状态,并且根据状态的变化,构建出新的Widget;

创建一个StatefulWidget,我们通常会按照如下格式来做:

当Flutter在构建Widget Tree时,会获取State的实例,并且它调用build方法去获取StatefulWidget希望构建的Widget;那么,我们就可以将需要保存的状态保存在MyState中,因为它是可变的;

1.2.2. 创建StatefulWidget

下面我们来看看代码实现:

因为当点击按钮时,数字会发生变化,所以我们需要使用一个StatefulWidget,所以我们需要创建两个类;MyCounterWidget继承自StatefulWidget,里面需要实现createState方法;MyCounterState继承自State,里面实现build方法,并且可以定义一些成员变量;

这样就可以实现想要的效果了:

首先,执行StatefulWidget中相关的方法:

1、执行StatefulWidget的构造函数(Constructor)来创建出StatefulWidget;2、执行StatefulWidget的createState方法,来创建一个维护StatefulWidget的State对象;

其次,调用createState创建State对象时,执行State类的相关方法:

1、执行State类的构造方法(Constructor)来创建State对象;

2、执行initState,我们通常会在这个方法中执行一些数据初始化的操作,或者也可能会发送网络请求;

注意:这个方法是重写父类的方法,必须调用super,因为父类中会进行一些其他操作;并且如果你阅读源码,你会发现这里有一个注解(annotation):@mustCallSuper

打印结果如下:

1.3.3. 生命周期的复杂版(选读)

我们来学习几个前面生命周期图中提到的属性,但是没有详细讲解的

1、mounted是State内部设置的一个属性,事实上我们不了解它也可以,但是如果你想深入了解它,会对State的机制理解更加清晰;

很多资料没有提到这个属性,但是我这里把它列出来,是内部设置的,不需要我们手动进行修改;

2.3. Flutter的编程范式

从2009年开始(数据来自维基百科),声明式编程就开始流行起来,并且目前在Vue、React、包括iOS中的SwiftUI中以及Flutter目前都采用了声明式编程

现在我们来开发一个需求:显示一个Hello World,之后又修改成了Hello Flutter

如果是传统的命令式编程,我们开发Flutter的模式很可能是这样的:(注意是想象中的伪代码)

整个过程,我们需要一步步告诉Flutter它需要做什么;

如果是声明式编程,我们通常会维护一套数据集:

这个数据集可能来自己父类、来自自身State管理、来自InheritedWidget、来自统一的状态管理的地方;总之,我们知道有这么一个数据集,并且告诉Flutter这些数据集在哪里使用;

上面的代码过于简单,可能不能体现出Flutter声明式编程的优势所在,但是在以后的开发中,我们都是按照这种模式在进行开始,我们一起来慢慢体会;

备注:所有内容首发于公众号,之后除了Flutter也会更新其他技术文章,TypeScript、React、Node、uniapp、mpvue、数据结构与算法等等,也会更新一些自己的学习心得等,欢迎大家关注

相关文章

暂住......别动,不想说点什么吗?
  • 全部评论(0
    还没有评论,快来抢沙发吧!