iOS开发Flutter探索-StatelessWidget&S
前言
上一篇文章我们了解了在Flutter中三种常见的布局方式Row
,Column
,Stack
,并对他们做了具体的举例和简单的应用。我们会在下一步的项目开发中做更具体的介绍和应用。今天给大家带来的是Flutter中两个核心的基类:StatelessWidget
(无状态部件)和StatefulWidget
(有状态部件),我们日常的开发中,自定义的小部件都是需要基于这两个类。接下来我们就对这两种类型的Widget做一些深入的探索。
StatelessWidget
StatelessWidget
-无状态小部件,这里的无状态体现在哪里呐?什么是个无状态?其实无状态的意思就是说当它被渲染到屏幕的那一刻,就无法改变了,就算内部做动态的数据修改,我的页面依然还是第一次呈现的样子。换句话说,就是我本身不具备重绘能力,我一开始是什么样子,我就一直是什么样字。接下来我们通过代码验证一下:
//这个代码就是新建的空工程内的那个点击➕,计数++的那个例子
//我们基于StatelessWidget创建一个MyHomePage部件
class MyHomePage extends StatelessWidget {
// final int count = 0; //final = let, statelessWidget 下变量的默认修饰符
int count = 0; //为了验证在无状态可以改变值,这里我们用可变的类型
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('StatelessWidget'),
),
body: Center(
child: Chip(label: Text('$count')), //这是个有圆角效果的label $xx flutter数据format
),
floatingActionButton: FloatingActionButton( //漂浮在右下角的button
child: Icon(Icons.add), //button 上的+icon
onPressed: (){ //点击事件 是一个callback 函数
count += 1;
print('count = $count'); //这里我们打印一下
},
),
);
}
}
控制台输出:
Performing hot reload...
Syncing files to device iPhone 11 Pro Max...
Reloaded 1 of 504 libraries in 940ms.
flutter: count = 1
flutter: count = 2
flutter: count = 3
flutter: count = 4
flutter: count = 5
flutter: count = 6
此时界面显示结果:
![](https://img.haomeiwen.com/i2019966/3f22ee739197d57d.png)
到此,我们会发现在StatelessWidget中是可以修改值的,只是修改完之后,并没有动态的渲染到屏幕上。这也就说明StatelessWidget是一个一次性渲染的Widget,一旦渲染到屏幕就不会再做任何改变。在项目中对于那些只做静态显示,没有数据变化的界面,我们就可以基于StatelessWidget来定义。
StatefulWidget
StatefulWidget
-有状态小部件,那这里的有状态又是怎么个体现呐?我们知道在iOS开发中,通过重写UIView
的drawRect:
方法后,当数据发生改变时,会通过调用setNeedsDisplay
方法,内部会通过调用其代理方法displayLayer
或drawLayer:inContext:
方法,将当前layer
的contents
中的内容删除,以便腾出新的空间,最后触发drawInRect:
方法进行重绘,将新的内容再交给contents,从而达到界面刷新效果。
每一个StatefulWiget
,都有一个State
与它一一对应,并遵守了当前Widget协议,并实现了build()
方法,在Widget中返回当前State
。(iOS角度的理解,可能不太准确,等进一步理解后再修改这里的描述吧)
class MyHomePage extends StatefulWidget {
// 这里还可以定义一些property
// 构造方法
// 对外暴露一些方法和属性
// createState() 建立绑定关系
@override
State<StatefulWidget> createState() { //获取当前State(或者说是建立Widget和State的绑定)
return _ZZState();
}
}
class _ZZState extends State<MyHomePage>{ //遵守MyHomePage协议/接口
int count = 0;
@override
Widget build(BuildContext context) { //重写build协议方法
return Scaffold(
appBar: AppBar(
title: Text('StateMangerDemo'),
),
body: Center(
child: Chip(label: Text('$count')),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: (){
count += 1; //当值发生改变时
setState(() {});// 类似于setNeedsDisplay->drawRect:
// 这里是 setState() -> build() 会抹掉当前Widget内容并重新绘制
print('count = $count');
},
),
);
}
}
当点击按钮时,控制台输出:
Performing hot restart...
Syncing files to device iPhone 11 Pro Max...
Restarted application in 2,449ms.
flutter: count = 1
flutter: count = 2
flutter: count = 3
flutter: count = 4
界面显示:
![](https://img.haomeiwen.com/i2019966/dcc2cd12aca93794.png)
就是这么简单,就是这么神奇! 关于
setState() -> build()
的原理,在后面的文章中会深入探索。
总结
本篇文章带大家了解了一下StatelessWidget
和StatefulWidget
基本概念和区别,并通过代码做了进一步的验证和演示。