Flutter入門04 -- Widget之StatelessWidget驼修,StatefulWidget

項目案例 -- 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í)行StatefulWidgetcreateState方法姐仅,創(chuàng)建一個維護StatefulWidgetState對象;
  • 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;
  • 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
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市厌均,隨后出現(xiàn)的幾起案子唬滑,更是在濱河造成了極大的恐慌,老刑警劉巖棺弊,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晶密,死亡現(xiàn)場離奇詭異,居然都是意外死亡模她,警方通過查閱死者的電腦和手機稻艰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侈净,“玉大人尊勿,你說我怎么就攤上這事⌒笳欤” “怎么了元扔?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長旋膳。 經(jīng)常有香客問我澎语,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任咏连,我火速辦了婚禮盯孙,結果婚禮上,老公的妹妹穿的比我還像新娘祟滴。我一直安慰自己振惰,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布垄懂。 她就那樣靜靜地躺著骑晶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪草慧。 梳的紋絲不亂的頭發(fā)上桶蛔,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音漫谷,去河邊找鬼仔雷。 笑死,一個胖子當著我的面吹牛舔示,可吹牛的內(nèi)容都是我干的碟婆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼惕稻,長吁一口氣:“原來是場噩夢啊……” “哼竖共!你這毒婦竟也來了?” 一聲冷哼從身側響起俺祠,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤公给,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜘渣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淌铐,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年蔫缸,在試婚紗的時候發(fā)現(xiàn)自己被綠了腿准。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡捂龄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出加叁,到底是詐尸還是另有隱情倦沧,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布它匕,位于F島的核電站展融,受9級特大地震影響,放射性物質發(fā)生泄漏豫柬。R本人自食惡果不足惜告希,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一扑浸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧燕偶,春花似錦喝噪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至伯诬,卻和暖如春晚唇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盗似。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工哩陕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赫舒。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓悍及,卻偏偏與公主長得像,于是被迫代替她去往敵國和親号阿。 傳聞我的和親對象是個殘疾皇子并鸵,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容