[Flutter Widget] StatefulWidget
Posted flutter开发者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Flutter Widget] StatefulWidget相关的知识,希望对你有一定的参考价值。
在前面的文章中我们学习了许多的控件,但是无一例外他们都不能处理界面的动态变更,我们无法在界面初始化后根据用户的操作去更改界面的展示方式。
是的这是一个很大的问题,但是在Flutter我们可以借助于StatefulWidget组件来完成界面的变更。
StatefulWidget又被称为有状态组件,开发者可以根据用户的操作来选择性的更新界面上的组件。
大家是否还记得我们每次创建项目,系统都会默认给我们生成的程序
每次当点击下面的FloatActionButton上面的数字就会+1
还是来看下官方代码是怎么实现的(为了便于大家理解我们去除了英文注释和无用参数设置)
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: new Center(
child:
new Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
child: new Icon(Icons.add),
),
);
}
}
代码很长对吧,希望大家不要被上面的代码吓到,其实还是跟原来的StatelessWidget的流程是一样的,只不过多了一个设置State的中间件而已。咱们来一点一点看下代码。
首先新建了一个App对象继承于StatelessWidget,返回了一哥MyHomePage对象。
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
MyHomePage对象继承于StateFulWdiget,但是继承StateFulWidget组件默认要返回继承于State的Wdiget,所以,MyHomePage又返回了一个_MyHomePageState对象
@override
_MyHomePageState createState() => new _MyHomePageState();
}
_MyHomePageState继承于State
void _incrementCounter() {
setState(() {
_counter++;
});
}
每当我们点击FloatActionButton按钮都会调用_incrementCounter方法,_incrementCounter方法会调用setState方法更新计数器的counter使其值+1,并且更新界面上View的状态。
由于界面上的Text的值是依据_counter的,所以每次更新界面都会显示最新的_counter的值,这样就达到了更新界面的效果。
关于点击事件
在上面的代码中大家可以看到floatingActionButton的onPressed点击事件我们传入了_incrementCounter,甚至连“()”也没有写。
从floatingActionButton的构造方法中我们可以看到,onPress需要传入的是一个没有返回值,没有参数的方即VoidCallback。
正好 _incrementCounter方法就是这么一个方法,所以我们可以直接把方法当做参数传入onPressed中。
举个例子
为了方便大家理解这个有状态组件,我们再来举个例子
内容区域是一个IndexedStack(栈里面依次放几个图标),默认加载第一个入栈的元素。下面是一个FloAtionButton,没当点击这个按钮是更新IndexedStack当前现实的元素位置,在这里我们使用Random来随机显示栈内Icons。
接下来,我们来看下代码:
void main() {
runApp(new MaterialApp(
home: new MyHome(),
));
}
class MyHome extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyHomeState();
}
}
首先,我们创建一个MyHome Widget继承于StatefulWidget,返回一个具有状态的MyhomeState组件。
class MyHomeState extends State<MyHome> {
int currentIndex = 0;
void _onFloatActionButtonPressed() {
setState(() {
currentIndex =new Random().nextInt(4);
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("StatefulWidget"),
),
body: new Center(
child: new IndexedStack(
index: currentIndex,
children: <Widget>[
new Icon(
Icons.cloud_download,
size: 100.0,
color: Colors.blue,
),
new Icon(
Icons.error_outline,
size: 100.0,
color: Colors.red,
),
new Icon(
Icons.check_circle,
size: 100.0,
color: Colors.green,
),
new Icon(
Icons.help,
size: 100.0,
color: Colors.yellowAccent,
)
],
)),
floatingActionButton: new FloatingActionButton(
onPressed: _onFloatActionButtonPressed,
child: new Icon(Icons.track_changes),
backgroundColor: Colors.blueAccent,
),
);
}
}
在MyHomeState中我们声明了一个变量currentIndex来记录栈内当前位置的值。
内部body是一个居中的IndexedStack,下面是一个floatingActionButton,每当我们点击这个按钮都会调用 _onFloatActionButtonPressed方法,更新currentIndex的值,然后更细UI显示效果。
上面的例子很简单,大家在平时的开发中可以根据用户操作的状态来显示指定的页面,如加载中、加载成功、加载失败、网络异常等状态。
小结
StateFulWidget是有状态组件,负责处理有状态的界面
使用setState回调可以很轻松的更新界面上UI的显示效果
有状态组件变更归根到底是根据数据变更来做的操作
VoidCallback是一个没有参数没有返回值的方法
试一试
今天的内容很简单,但是还是需要熟悉Flutter中有状态组件的用法,因为这个是最重要的概念哦。
那么大家试一试官方Demo让中间计数器的字体大小随着计数器的值变化。
当然,有什么问题也欢迎大家在后台留言,我会在看到的第一时间回复大家的
以上是关于[Flutter Widget] StatefulWidget的主要内容,如果未能解决你的问题,请参考以下文章
Flutter控件篇(Stateful widget)——ListView
Flutter - Stateful(有状态) 和 stateless(无状态) widgets
跨多个屏幕使用的 Flutter Stateful Widget 正在重建
Flutter Stateful Widget 状态未初始化