項目案例 -- StatelessWidget
- 案例代碼如下:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
main() => runApp(SFMyApp());
class SFMyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SFHomePage(),
);
}
}
class SFHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("商品列表"),
),
body: SFContentBody(),
);
}
}
class SFContentBody extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ListView(
children: [
SFProductItem("Apple1","MacBook1","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdl.bbs.9game.cn%2Fattachments%2Fforum%2F201507%2F29%2F154250no2g2zqiuiqvaiku.jpg&refer=http%3A%2F%2Fdl.bbs.9game.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1637072364&t=07974f838e1b49ecdecaba22f4af4fa2"),
SFProductItem("Apple2","MacBook2","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdl.bbs.9game.cn%2Fattachments%2Fforum%2F201507%2F29%2F154250no2g2zqiuiqvaiku.jpg&refer=http%3A%2F%2Fdl.bbs.9game.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1637072364&t=07974f838e1b49ecdecaba22f4af4fa2"),
SFProductItem("Apple3","MacBook3","https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fdl.bbs.9game.cn%2Fattachments%2Fforum%2F201507%2F29%2F154250no2g2zqiuiqvaiku.jpg&refer=http%3A%2F%2Fdl.bbs.9game.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1637072364&t=07974f838e1b49ecdecaba22f4af4fa2"),
],
);
}
}
class SFProductItem extends StatelessWidget {
final String title;
final String desc;
final String imageUrl;
final titleStyle = TextStyle(fontSize: 25,color: Colors.orange);
final descStyle = TextStyle(fontSize: 20,color: Colors.green);
//自定義構造函數(shù)
SFProductItem(this.title,this.desc,this.imageUrl);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(8), //設置內(nèi)邊距
decoration: BoxDecoration(
border: Border.all(
width: 5, //設置邊框的寬度
color: Colors.purple //設置邊框的額顏色
)
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title,style: titleStyle),
SizedBox(height: 8),//設置間距
Text(desc,style: descStyle),
SizedBox(height: 8),
Image.network(imageUrl)
],
),
);
}
}
- 效果如下所示:
image.png
- 給widget添加Container的快捷鍵
Alt + Enter
- widget之間
設置間距
使用SizedBox(height: 8)
項目案例 -- StatefulWidget
-
StatefulWidget
最大的特點是:StatefulWidget
通過創(chuàng)建狀態(tài)類_SFHomeContentState
拼窥,來管理自己的狀態(tài)數(shù)據(jù)殖演; - 案例代碼如下:
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() => runApp(SFMyApp());
class SFMyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SFHomePage()
);
}
}
class SFHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("商品列表")
),
body: SFHomeContent("上面是一個簡單的計數(shù)器")
);
}
}
class SFHomeContent extends StatefulWidget {
final String message;
SFHomeContent(this.message);
@override
State<StatefulWidget> createState() {
return _SFHomeContentState();
}
}
//
class _SFHomeContentState extends State<SFHomeContent>{
var _counter = 0;
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_getButtons(),
Text("當前計數(shù): $_counter",style: TextStyle(fontSize: 20)),
Text("${widget.message}",style: TextStyle(fontSize: 18))
],
),
);
}
Widget _getButtons(){
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
child: Text("+",style: TextStyle(fontSize: 20,color: Colors.white)),
color: Colors.pink,
onPressed: (){
print("點擊+");
setState(() {
_counter++;
});
},
),
RaisedButton(
child: Text("-",style: TextStyle(fontSize: 20,color: Colors.white)),
color: Colors.purple,
onPressed: (){
print("點擊-");
setState(() {
_counter--;
});
},
)
],
);
}
}
-
class _SFHomeContentState extends State<SFHomeContent>
假栓,Widget _getButtons()
類名與方法名之前加下劃線
表明屬于私有的; -
class _SFHomeContentState extends State<SFHomeContent>
:_SFHomeContentState
狀態(tài)用來管理SFHomeContent
這個widget的狀態(tài)數(shù)據(jù)的点晴,即_SFHomeContentState
會綁定SFHomeContent
感凤,_SFHomeContentState
中能通過widget屬性
訪問SFHomeContent
中的內(nèi)容; - 代碼運行效果:
image.png
StatefulWidget生命周期
- 所謂生命周期是指:目標組件從創(chuàng)建到銷毀的整個過程粒督,監(jiān)聽組件的生命周期以便在不同的時期執(zhí)行不同的邏輯陪竿;
- Flutter組件的生命周期:
-
StatelessWidget
可以由父widget直接傳入值,調(diào)用build
方法來創(chuàng)建屠橄,整個過程非常簡單族跛,其生命周期,主要關注構造函數(shù)
與build
方法锐墙; -
StatefulWidget
需要通過State
來管理其狀態(tài)數(shù)據(jù)礁哄,并且監(jiān)聽狀態(tài)的改變重新build整個widget;
-
-
StatefulWidget
生命周期的過程如下圖所示:
Snip20211018_14.png - 1.執(zhí)行
StatefulWidget
的構造函數(shù)溪北; - 2.執(zhí)行
StatefulWidget
的createState
方法姐仅,創(chuàng)建一個維護StatefulWidget
的State
對象; - 3.執(zhí)行
State
的構造方法刻盐; - 4.執(zhí)行
initState
方法,我們通常在此方法中執(zhí)行一些數(shù)據(jù)初始化
操作劳翰,或者發(fā)送網(wǎng)絡請求
敦锌; - 5.
didChangeDependencies
方法,在下面兩種情況下會調(diào)用:- 調(diào)用
initState
時會調(diào)用佳簸; - 從其他對象中依賴一些數(shù)據(jù)發(fā)生改變時乙墙,比如InheritedWidget;
- 調(diào)用
- 6.執(zhí)行
build
方法生均,渲染widget樹听想; - 7.當 當前的widget不再使用時,會調(diào)用
dispose
方法進行銷毀马胧; - 8.手動調(diào)用
setState
方法汉买,會根據(jù)最新的狀態(tài)數(shù)據(jù)來重新調(diào)用build
方法,構建對應的widget佩脊; - 9.執(zhí)行
didUpdateWidget
方法是在父widget觸發(fā)重建rebuild時蛙粘,系統(tǒng)會調(diào)用didUpdateWidget
方法垫卤; - 代碼案例驗證:
import 'package:flutter/material.dart';
void main() => runApp(SFMyApp());
class SFMyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: SFHomePage()
);
}
}
class SFHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("商品列表")
),
body: SFHomeContent("上面是一個簡單的計數(shù)器")
);
}
}
class SFHomeContent extends StatefulWidget {
final String message;
SFHomeContent(this.message){
print("SFHomeContent 構造方法");
}
@override
State<StatefulWidget> createState() {
print("createState");
return _SFHomeContentState();
}
}
class _SFHomeContentState extends State<SFHomeContent>{
var _counter = 0;
_SFHomeContentState(){
print("_SFHomeContentState 構造方法");
}
@override
void initState() {
super.initState();
print("_SFHomeContentState initState");
}
@override
Widget build(BuildContext context) {
print("_SFHomeContentState build");
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
child: Text("+",style: TextStyle(fontSize: 25,color: Colors.white)),
color: Colors.pinkAccent,
onPressed: (){
setState(() {
_counter++;
});
},
),
Text("${widget.message}",style: TextStyle(fontSize: 18))
],
),
);
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("_SFHomeContentState didChangeDependencies");
}
@override
void didUpdateWidget(SFHomeContent oldWidget) {
super.didUpdateWidget(oldWidget);
print("_SFHomeContentState didUpdateWidget");
}
-
@override
void dispose() {
super.dispose();
print("_SFHomeContentState dispose");
}
}
- 執(zhí)行結果如下:
image.png
-
StatefulWidget
生命周期復雜版的過程如下圖所示:
Snip20211018_13.png mounded
時State內(nèi)部設置的一個屬性,不需要我們手動進行修改的出牧,其主要作用是記錄widget
對應的element
是否為空穴肘;dirty state
含義是臟的state,它實際是來標記Element
的舔痕,標記為dirty的Element會等待下一次的重繪檢查评抚,強制調(diào)用build方法
來構建我們的widget;clean state
含義是干凈的state伯复,它表示當前build出來的widget慨代,下一次重繪檢查不需要重新build;
Flutter的編程范式
- 命令式編程:就是一步步給計算機命令边翼,告訴它我們想做什么事情鱼响;
- 聲明式編程:通常是描述目標的性質,依賴哪些狀態(tài)组底,并且當依賴的狀態(tài)發(fā)生改變時丈积,我們通過某些方式通知目標做出響應,聲明式編程是依賴框架的债鸡;
- Flutter采用的是聲明式編程江滨;
- 命令式編程的代碼案例:
final text = new Text();
var title = "Hello World";
text.setContent(title); //主動設置title
- 聲明式編程的代碼案例:
var title = "Hello World";
Text(title); //告訴Text內(nèi)部顯示的是title