这个转自我自己的有道云 想看图片去那里
文档:Day3_2 StatelessWidget 和 StatefulWi…
链接:http://note.youdao.com/noteshare?id=71abe63a08ed806e44911f636b452b44&sub=AC2B27FCC2AA41FE86AB93B15475B063
StatelessWidget 和 StatefulWidget
- StatelessWidget 的案例
- StatefulWidget 的案例
- StatefulWidget的生命周期
1. StatelessWidget
我们经过之前的练习知道了, 这个东西是无状态的Widget, 他的数据是不能变的
StatelessWidget练习
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rzraKNvW-1583548791492)(4DAC89A36141444591BDE15A137B9CC5)]
我们从头写起
import 'package:flutter/material.dart';
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container();
}
}
然后把框架搭好
- 我们发现直接写extends StatelessWidget速度太慢, 所以这里可以使用一个快速的写法
- 我们写出stl 然后回车就可以快速打出 对应的继承代码
- 但是我们要使用material的样式而且要展示home界面所以需要这样嵌套
Scaffold 这个东西就像Android中的Activity 是一样的
import 'package:flutter/material.dart';
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage()
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StatelessWidget练习")
),
body: HYHomeList(),
);
// 注意这里和java 那些东西不一样需要加分号
}
}
class HYHomeList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQuy2NTk-1583548791494)(D1785F6E751A4EA58D078E59808124EE)]
然后我们观察这个项目的结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hHjZXyaw-1583548791496)(93E9474DD60046048B3C898ACE94CA6F)]
我们先写出框架
- 因为我们这里是从上往下放多个所以这里是Column
- 如果是放多个就是children, 放一个就是child
import 'package:flutter/material.dart';
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage()
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StatelessWidget练习")
),
body: HYHomeList(),
);
// 注意这里和java 那些东西不一样需要加分号
}
}
class HYHomeList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text("hahah"),
Text("hahha"),
Text("hahaha")
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TTcdlZnL-1583548791496)(4187A953B1F14A46AFDD2E12ECFEA8C6)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HIOeRhl7-1583548791497)(93E9474DD60046048B3C898ACE94CA6F)]
这个里面也是一个Column
HYHomeListItem 的设计
- 因为这个很明显, 他需要显示不同的内容
- 我们flutter是一个面向对象的语言
所以我们的Widget可以设置成要传参数的那种
import 'package:flutter/material.dart';
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage()
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StatelessWidget练习")
),
body: HYHomeList(),
);
// 注意这里和java 那些东西不一样需要加分号
}
}
class HYHomeList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-04-22/b0201606065bcdad3159cd02c9199a01.jpg"),
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-07-27/c4d6ea4d8c51e0aa3c750aed13913a1b.jpg"),
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/celve/2019-03-04/55ce1f75dac4b12a4aae1ec691b83400.jpg")
],
);
}
}
class HYHomeListItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
HYHomeListItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(title),
Text(desc),
Image.network(imageURL)
],
);
}
}
所以这个里面也是item Widget
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vG7qnv4P-1583548791497)(70C3F731820246E7ADC926AA5AE6A1C2)]
但是下面报错了
A RenderFlex overflowed by 285 pixels on the bottom.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8uKNOSol-1583548791498)(2C12B763EB14423AA00843860FD9CEC9)]
意思是说超出了, 我们的Widget超出了屏幕的范围
我们换用ListView代替最外面的Column, 让最外面可以滚动这个问题就可以解决了
import 'package:flutter/material.dart';
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage()
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StatelessWidget练习")
),
body: HYHomeList(),
);
// 注意这里和java 那些东西不一样需要加分号
}
}
class HYHomeList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-04-22/b0201606065bcdad3159cd02c9199a01.jpg"),
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-07-27/c4d6ea4d8c51e0aa3c750aed13913a1b.jpg"),
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/celve/2019-03-04/55ce1f75dac4b12a4aae1ec691b83400.jpg")
],
);
}
}
class HYHomeListItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
HYHomeListItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(title),
Text(desc),
Image.network(imageURL)
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K1Vlbhnt-1583548791499)(0D7949F3C6174E9CA7E2DAFCA985B5A3)]
但是如果我们不希望你居中
- 这个时候我们可以设置itemWidget中的Column交叉轴属性
但是这个不是一般的做法
class HYHomeListItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
HYHomeListItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Text(title),
Text(desc),
Image.network(imageURL)
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Kp0vHDe-1583548791499)(CEB3740EDFFA40BFBC904B41995AF078)]
这样我们就可以居左居右了
- 但是如果你想title居左 desc居右 那我们就需要在里面再嵌入Row让里面的东西可以自行设置他的居左居右
- 注意这个Row是占据一整行的
这个就是一般做法
class HYHomeListItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
HYHomeListItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(title),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(desc),
],
),
Image.network(imageURL)
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5E7i9OH3-1583548791500)(42F45FFB5A8F4AAF97CBB0D7B7292AFC)]
调整样式
class HYHomeListItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
HYHomeListItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(title, style: TextStyle(fontSize: 30, color: Colors.red),),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(desc, style: TextStyle(fontSize: 20, color: Colors.blue)),
],
),
Image.network(imageURL)
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OSjgRgGM-1583548791500)(53C41C5F1A61452CA6364E5469558B1E)]
设置外边距
然后我如果希望这些Widget间有些间距的话我们可以使用SizedBox
- 一般来说如果我们使用的是html那种东西的话, 我们因该是设置类似于margin-top 之类的东西
- 但是在flutterz中我们没有这种东西
- 所以我们为了撑高度使用的是SizedBox(height: number)
- 如果想要左右边距的话我们使用Alignment就可以了
因为flutter中万物皆Widget所以margin 这种也是属于Widget的(当然有些是属于widget的属性的)
class HYHomeList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: <Widget>[
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-04-22/b0201606065bcdad3159cd02c9199a01.jpg"),
SizedBox(height: 10),
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-07-27/c4d6ea4d8c51e0aa3c750aed13913a1b.jpg"),
SizedBox(height: 10),
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/celve/2019-03-04/55ce1f75dac4b12a4aae1ec691b83400.jpg")
],
);
}
}
class HYHomeListItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
HYHomeListItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(title, style: TextStyle(fontSize: 30, color: Colors.red),),
],
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(desc, style: TextStyle(fontSize: 20, color: Colors.blue)),
],
),
SizedBox(height: 8),
Image.network(imageURL)
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NhdSW4xF-1583548791501)(F5D7CDE5D2364A4DB592BAC917707F2F)]
设置内边距
如果我们觉得这个东西挨着边框不好看
那么我们可以设置他的padding
这个东西padding: EdgeInsets.all(8) 直接在ListView上面加
class HYHomeList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
padding: EdgeInsets.all(8),
children: <Widget>[
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-04-22/b0201606065bcdad3159cd02c9199a01.jpg"),
SizedBox(height: 10),
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-07-27/c4d6ea4d8c51e0aa3c750aed13913a1b.jpg"),
SizedBox(height: 10),
HYHomeListItem("title", "desc", "https://www.lianaiyx.com/d/file/celve/2019-03-04/55ce1f75dac4b12a4aae1ec691b83400.jpg")
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d1KU53zu-1583548791502)(435875AA074941298D05F5D119E78BE3)]
设置边框
然后我们觉得这个还是有一个边框比较好
这个东西因该加在item上面但是item没有这个属性
- 边框这个东西需要Container来设置, 其实就是一个普通的Widget
- 因为Column是装多个widget给他设置border肯定不合适
- 这里我们使用alt + enter 加上container包裹的快捷键
- 然后设置Container的border
class HYHomeListItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
HYHomeListItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
border: Border.all(
width: 5,
color: Colors.red
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(title, style: TextStyle(fontSize: 30, color: Colors.red),),
],
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(desc, style: TextStyle(fontSize: 20, color: Colors.blue)),
],
),
SizedBox(height: 8),
Image.network(imageURL)
],
),
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifyRVLwW-1583548791502)(7C13287C51C046158B01D00FF54A0653)]
StatalessWidget完整代码
import 'package:flutter/material.dart';
main() => runApp(MyApp());
//直接写效率太低了
//我们直接敲stl就会生成对应的代码
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: HYHomePage(),
// 这个就是一启动显示的页面
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("商品列表")
),
body: HYHomeContent(),
);
}
}
class HYHomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 现在只是想回顾一下这个StatelessWidget
return ListView(
// 要放多个 所以是children 不是 child
children: <Widget>[
// 我们因该在里面放商品数据
// The specific RenderFlex in question is: RenderFlex#af73a relayoutBoundary=up1 OVERFLOWING
// 这个是操作布局边界 希望让它变成可滚动的区域
HYHomeProductItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-04-22/b0201606065bcdad3159cd02c9199a01.jpg"),
SizedBox(height: 6),
HYHomeProductItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-07-27/c4d6ea4d8c51e0aa3c750aed13913a1b.jpg"),
SizedBox(height: 6),
HYHomeProductItem("title", "desc", "https://www.lianaiyx.com/d/file/GalGame/2019-03-05/6c815fb726391c117d1d6b0a126fa643.jpg"),
],
);
}
}
//我们使用同一个Widget但是我们希望展示的东西是不一样的
//
class HYHomeProductItem extends StatelessWidget {
final String title;
final String desc;
final String imageURL;
final style1 = TextStyle(fontSize: 25, color: Colors.orange);
final style2 = TextStyle(fontSize: 20, color: Colors.green);
HYHomeProductItem(this.title, this.desc, this.imageURL);
@override
Widget build(BuildContext context) {
// 我们现在想要设计一个边框
// 如果想要包裹一个widget我们可以使用alt + enter
return Container(
// 如果我们希望和里面的东西有一个内边距
padding: EdgeInsets.all(12),
// decoration这个东西是一个抽象类
decoration: BoxDecoration(
// ctrl + alt + B 就可以看到它的实现类
border: Border.all(
// 这个东西就是设置边框的宽度
width: 5,
// 设置边框颜色
color: Colors.black12
// 这个12是一个透明度的意思
)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
// 但是实际上我们因该通过 交叉轴而是在里面嵌套 Row然后在里面
children: <Widget>[
// 我们想要居右
// , textAlign: TextAlign.right 这个没有用 文本是包裹内容的所以居左居右
// 这个东西是Column所以我们设置的是它的交叉轴
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(title, style: style1, textAlign: TextAlign.right),
],
),
// flutter没有margin-top之类的东西所以
SizedBox(height: 8),
Row(
children: <Widget>[
Text(desc, style: style2),
],
),
// 这个八个像素 但是是和设备有关系
// 后面
// 如果是想要左右边距离的话Alignmen就可以了
SizedBox(height: 8),
Row(
children: <Widget>[
Image.network(imageURL)
],
)
],
),
);
}
}
2. StatefulWidget的使用示例
- 为什么flutter在设计的时候StatefulWidget的build方法放在State中
- build出来的Widget是需要以来State中的变量(状态)
- flutter运行过程中Widget是不断销毁创建的 Element-Render-Object
- 当时我们状态发生改变的时候, 并不希望创建一个新的State
所以我们呢才会将StatefulWidget和State实现类分离
实例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZVuEUKM7-1583548791502)(1FF62F62A746427D8D1194B6D6714C51)]
- 首先我们搭建出平台
import "package:flutter/material.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return HYHomePage();
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomeContent(),
);
}
}
class HYHomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("statefulWidget示例"),
),
body: Text("test")
);
}
}
如果我们要做计数器很明显我们需要具有状态的Widget
所以就需要用StatefulWidget
import "package:flutter/material.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage(),
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("statefulWidget示例"),
),
body: Text("test")
);
}
}
class HYHomeContent extends StatefulWidget {
@override
_HYHomeContentState createState() => _HYHomeContentState();
}
class _HYHomeContentState extends State<HYHomeContent> {
@override
Widget build(BuildContext context) {
return Container();
}
}
然后就是结构和StatelessWidget不同是的我们的渲染的框架是在继承StatefulWidget, 因该是写在State里面
import "package:flutter/material.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage(),
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("statefulWidget示例"),
),
body: Center(child:HYHomeContent())
);
}
}
class HYHomeContent extends StatefulWidget {
@override
_HYHomeContentState createState() => _HYHomeContentState();
}
class _HYHomeContentState extends State<HYHomeContent> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text("+", style: TextStyle(color: Colors.white)),
onPressed: () {
},
),
RaisedButton(
color: Colors.green,
child: Text("-", style: TextStyle(color: Colors.white)),
onPressed: () {
},
)
],
),
Text("counter: $_counter")
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TshD7TJE-1583548791503)(236D8204F87B4A6283A0CD5579F74810)]
但是我们直接改变变量的值还是不行的
- 我们必须要调用setState刷新
- 这个东西就是调用刷新页面的意思, 所以你如果把变量的改变写在前面写在后面都是一样的
- 再强调一遍私有属性是会加_ 加了只有这个变量就会只属于这个 库
- 这个注意 这里如果要分离State的作为一个新的widget则是是需要将我们的函数作为闭包传过去 然后在那边调用
import "package:flutter/material.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage(),
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("statefulWidget示例"),
),
body: Center(child:HYHomeContent())
);
}
}
class HYHomeContent extends StatefulWidget {
@override
_HYHomeContentState createState() => _HYHomeContentState();
}
class _HYHomeContentState extends State<HYHomeContent> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text("+", style: TextStyle(color: Colors.white)),
onPressed: () {
++_counter;
setState(() {
});
},
),
RaisedButton(
color: Colors.green,
child: Text("-", style: TextStyle(color: Colors.white)),
onPressed: () {
setState(() {
--_counter;
});
},
)
],
),
Text("counter: $_counter")
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fvcLFTYQ-1583548791503)(6C3739A610094A2F8631AC662BDBC587)]
我们看到源码里面其实它也是在setState里面调了传进去的参数的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aTQ4ALCN-1583548791504)(04E6A1BEBEDD4139A8BCC168D705E8AD)]
指向StatefulWidget的指针
还有如果你想要再StatefulWidget中传参数 然后再后面展示
可以再传的方式 也可以用state指向StatefulWidget对象的指针来实现这个功能
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("statefulWidget示例"),
),
body: Center(child:HYHomeContent("传递的参数"))
);
}
}
class HYHomeContent extends StatefulWidget {
final String message;
HYHomeContent(this.message);
@override
_HYHomeContentState createState() => _HYHomeContentState();
}
class _HYHomeContentState extends State<HYHomeContent> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.red,
child: Text("+", style: TextStyle(color: Colors.white)),
onPressed: () {
++_counter;
setState(() {
});
},
),
RaisedButton(
color: Colors.green,
child: Text("-", style: TextStyle(color: Colors.white)),
onPressed: () {
setState(() {
--_counter;
});
},
)
],
),
Text("counter: $_counter ${widget.message}")
],
);
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tKOKjZkB-1583548791505)(79250287C7004999B1970578F4AACF0D)]
3. StatfulWidget和StatelessWidget的生命周期函数
- 生命周期函数也被称为“hook” “钩子函数”
- 其主要功能就是在程序运行到指定位置时进行回调
- 生命周期函数的功能
- 初始化一些数据, 变量, 状态
- 发送网络请求
- 监听组件中的事件 controller 添加监听事件(滚动事件)
- 管理内存: 一些定时器-controller手动进行销毁
StatelessWidget的生命周期函数很简单
主要就是StatelessWidget构造函数和build函数
其实就是没有专门的生命周期函数, 因为它没有状态, 所以它也简单的多
import "package:flutter/material.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage()
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("title")
),
body: HYHomeContent()
);
}
}
class HYHomeContent extends StatelessWidget {
HYHomeContent() {
print("HYHomeContent 构造函数执行");
}
@override
Widget build(BuildContext context) {
print("HYHomeConten build函数执行");
return Text("content");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XxPaQwMg-1583548791505)(530E35C0AA264130B6EC3915933ECDE0)]
StatefulWidget的生命周期函数
重要
先建立一个简单的StatefulWidget
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ip2UwgJp-1583548791505)(5CF4FCB23BB740C7A6855B909120D2CB)]
import "package:flutter/material.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage()
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StatefulWidget的生命周期函数")
),
body: HYHomeContent()
);
}
}
class HYHomeContent extends StatefulWidget {
@override
_HYHomeContentState createState() => _HYHomeContentState();
}
class _HYHomeContentState extends State<HYHomeContent> {
int _counter = 0;
// 如果我们想要拆分这个东西因该怎么办
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
RaisedButton(
child: Text("+"),
onPressed: () {
setState(() {
_counter++;
});
},
),
Text("counter: $_counter")
],
);
}
}
然后将生命周期函数写上去
- StatefulWidget子类的构造方法
- StatefulWidget子类的createState方法
- State子类的构造方法
- State子类的initState方法
- State子类的build方法
- State子类的dispose方法
import "package:flutter/material.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage()
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StatefulWidget的生命周期函数")
),
body: HYHomeContent()
);
}
}
class HYHomeContent extends StatefulWidget {
HYHomeContent() {
print("1. 调用HYHomeContent的构造函数");
}
@override
_HYHomeContentState createState() {
print("2. 调用HYhomeContent的createState方法");
return _HYHomeContentState();
}
}
class _HYHomeContentState extends State<HYHomeContent> {
int _counter = 0;
_HYHomeContentState() {
print("3. 调用_HYHomeContentState的构造函数");
}
@override
void initState() {
// TODO: implement initState
print("4. 调用_HYHomeContentState的initState方法");
// 下面这个必须写
super.initState();
}
// 如果我们想要拆分这个东西因该怎么办
@override
Widget build(BuildContext context) {
print("5. 调用_HYHomeContentState的build方法");
return Column(
children: <Widget>[
RaisedButton(
child: Text("+"),
onPressed: () {
setState(() {
_counter++;
});
},
),
Text("counter: $_counter")
],
);
}
@override
void dispose() {
// TODO: implement dispose
print("6. 调用_HYHomeContentState的dispose方法");
super.dispose();
}
}
后面这个反复调用是Android Studio 的bug, vscode就没有
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mqD1bPq3-1583548791506)(B0C29EE84CBF40A4B8090FBCF3943420)]
- 在我们点击+以后 会不停的调用build
- 这个过程其实也就是不停重建Widget过程
- 这个也是验证了Widget是不停的销毁和创建的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1dshXOXz-1583548791506)(F25C1882E1ED4A8DB29BD6B0A6EFAEA8)]
还有一些其他的生命周期函数那些不是很常用但是还是需要知道
import "package:flutter/material.dart";
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HYHomePage()
);
}
}
class HYHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("StatefulWidget的生命周期函数")
),
body: HYHomeContent()
);
}
}
class HYHomeContent extends StatefulWidget {
HYHomeContent() {
print("1. 调用HYHomeContent的构造函数");
}
@override
_HYHomeContentState createState() {
print("2. 调用HYhomeContent的createState方法");
return _HYHomeContentState();
}
}
class _HYHomeContentState extends State<HYHomeContent> {
int _counter = 0;
_HYHomeContentState() {
print("3. 调用_HYHomeContentState的构造函数");
}
@override
void initState() {
// TODO: implement initState
print("4. 调用_HYHomeContentState的initState方法");
// 下面这个必须写
super.initState();
}
@override
void didUpdateWidget(HYHomeContent oldWidget) {
// TODO: implement didUpdateWidget
print("调用——HYHomeContentState的didUpdateWidget方法");
super.didUpdateWidget(oldWidget);
}
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
// 這個數據依賴一些東西的時候 依賴的東西改變了就會調用
// 就是裏面的東西 假如依賴了 InheritedWidget的message 假如這個改變了
// 就會調用didChangeDependecies
print("调用_HYHomeContenState的didChangeDepancies");
super.didChangeDependencies();
}
// 如果我们想要拆分这个东西因该怎么办
@override
Widget build(BuildContext context) {
print("5. 调用_HYHomeContentState的build方法");
return Column(
children: <Widget>[
RaisedButton(
child: Text("+"),
onPressed: () {
setState(() {
_counter++;
});
},
),
Text("counter: $_counter")
],
);
}
@override
void dispose() {
// TODO: implement dispose
print("6. 调用_HYHomeContentState的dispose方法");
super.dispose();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WtZcALT6-1583548791507)(B51E30A28D63489492042D24E7DF0BA4)]