Flutter中的widget和其生命周期

1.Widget

在Flutter中所有的組成都是widget,可以成為組件或者控件
Widget可以分為2類

  1. StatelessWidget:一般適用于固定界面布局
  2. StatefulWidge:t用于界面數(shù)據(jù)交互傳遞
  1. Widget的源碼中,我們可以發(fā)現(xiàn)@immutable關(guān)鍵字,是不可變的,所以反正extends繼承的組件,實(shí)例化中的成員變成,需要使用final修飾
  2. Widget的是一個(gè)abstract修飾的抽象類,里面定義了方法API 需要我們自己手動(dòng)實(shí)現(xiàn)
image

2.StatelessWidget

StatelessWidget也是一個(gè)抽象類,我們要實(shí)現(xiàn)bulid方法返回一個(gè)widget實(shí)例
通過(guò)一個(gè)小例子說(shuō)明

image
//導(dǎo)入material的設(shè)計(jì)風(fēng)格 庫(kù)
import 'package:flutter/material.dart';
  main(){
  //調(diào)用系統(tǒng)的runApp方法
  //創(chuàng)建自定義的widget實(shí)例 MyApp()
  runApp(MyApp());
}

調(diào)用runApp()方法是需要傳入一個(gè)widget對(duì)象實(shí)例

image
// 1.創(chuàng)建一個(gè)MyAPP類
class MyApp extends StatelessWidget {
  // 2.重寫build方法
  @override
  Widget build(BuildContext context) {
   //返回一個(gè) widget實(shí)例
    return MaterialApp(
      home: JCHome(),
    );
  }
}

//首頁(yè)
// Scaffold腳手架,類似iOS中的ViewController
class JCHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //初始化一個(gè)腳手架
    return Scaffold(
      appBar: AppBar(
        title: Text("一個(gè)認(rèn)知Flutter的案例"),
      ),
      body:JCHomeContent(),
    );
  }
}


//內(nèi)容
class JCHomeContent extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    //創(chuàng)建一個(gè)ListView
    return ListView(
      children: <Widget>[
        JCHomeGoods("商品一", "這是一本奇書", "http://t9.baidu.com/it/u=1307125826,3433407105&fm=79&app=86&f=JPEG?w=5760&h=3240"),
        JCHomeGoods("風(fēng)景二", "這是一本奇書", "http://img.shu163.com/uploadfiles/wallpaper/2010/6/2010082606113848.jpg"),
        JCHomeGoods("狗狗", "這是一本奇書", "http://pic1.win4000.com/wallpaper/e/5652d1b71a9f1.jpg"),

      ],
    );
  }
}



//列表對(duì)象
// 注意 widget是用 immutable 修飾的,意思說(shuō)是不可變化的 所以其子類成員變量需要使用final

class JCHomeGoods extends StatelessWidget {

  final String title;
  final String des;
  final String imagePath;

  //實(shí)現(xiàn)便利構(gòu)造器方法
  JCHomeGoods(this.title,this.des,this.imagePath);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return  Container(
      padding: EdgeInsets.all(10),
      //修飾
      decoration: BoxDecoration(
        //邊框
        border: Border(
          //底部邊框
          bottom: BorderSide(
            color: Colors.black12,
            width: 5,
          )
        )
      ),
      child:  Column(
        //側(cè)抽對(duì)其方式
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(title,style: TextStyle(
            fontSize: 20,
            color: Colors.red
          ),),
          SizedBox(height: 8,),
          Text(des,style: TextStyle(
            fontSize: 18,
            color: Colors.orange
          ),),
          Image.network(imagePath)
        ],
      ),
    ) ;
  }
}

3. StatefulWidget

  1. 只要有界面數(shù)據(jù)發(fā)生變化就需要繼承StatefulWidget
  2. StatefulWidget是用來(lái)存儲(chǔ)狀態(tài)變化的
  • 2.1 繼承 StatefulWidget的組件,需要自己常見一個(gè)State狀態(tài)類,來(lái)管理狀態(tài)的變化
  • 2.2 通過(guò)定義的狀態(tài)類,重新實(shí)現(xiàn)build方法,構(gòu)建一個(gè)widget來(lái)更新界面數(shù)據(jù)


//這個(gè)界面有狀態(tài)發(fā)生了變化 這里需要?jiǎng)?chuàng)建一個(gè)State狀態(tài)
class JCHomeContent extends StatefulWidget {

  @override
  State<StatefulWidget> createState() {
    //返回一個(gè)State狀態(tài)類
    return JCState();
  }
}


//創(chuàng)建一個(gè)狀態(tài)管理類 用來(lái)管理狀態(tài) 泛型你的StatefulWidget
//當(dāng)狀態(tài)發(fā)生變化的時(shí)候調(diào)用 setState() 方法改變
class JCState extends State <JCHomeContent> {

  //定義一個(gè)變量
  var flag = false;

 
  @override
  Widget build(BuildContext context) {
    return Text();
  }
}



在這里插入圖片描述
例子

import 'package:flutter/material.dart';


//main函數(shù)入口
main() => runApp(MyApp());


//MyApp類
class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home:JCHomePage() ,
    );
  }

}


//創(chuàng)建一個(gè)JCHomePage的widget類
class JCHomePage extends StatelessWidget {

   @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("StatefulWidget的認(rèn)知"),
      ),
      body: JCHomeContent(),
    );
  }
}


//創(chuàng)建一個(gè) JCHomeContent繼承StatefulWidget
class JCHomeContent extends StatefulWidget {

  //創(chuàng)建一個(gè)State的子類來(lái)管來(lái)狀態(tài)
   @override
  State<StatefulWidget> createState() {

    return _JCState();
  }
}


// 注意: 帶_的類或者成員變量,都只能在自己的模塊中使用,正在其他模塊不能被使用的,屬于自己私有

class _JCState extends State<JCHomeContent>{

   int _count = 0;

  @override
  Widget build(BuildContext context) {

    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          RaisedButton(
            child: Text(
              "點(diǎn)擊+1",
              style: TextStyle(
                fontSize: 20,
                color: Colors.white
              ),
            ),
            color:Colors.pink ,
              onPressed: (){
              //更新數(shù)據(jù)狀態(tài)
                setState(() {
                   this._count ++;
                });
              }
              ),
          SizedBox(height: 8,),
          Text(
            "當(dāng)前數(shù)字是:${this._count}",
            style: TextStyle(
              fontSize: 20
            ),
          ),
        ],
      ),
    );
  }
}







4. 生命周期

4.1StatelessWidget的生命周期

StatelessWidget的生命周期 比較簡(jiǎn)單 ,調(diào)用widget的build方法就完成了


//創(chuàng)建一個(gè)JCHomePage的widget類
class JCHomePage extends StatelessWidget {
  
  //重寫build方法
   @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("StatefulWidget的認(rèn)知"),
      ),
      body: JCHomeContent(),
    );
  }
}

4.2 StatefulWidget生命周期
此圖片來(lái)自網(wǎng)絡(luò)
  1. 調(diào)用繼承StatefulWidget組件的 構(gòu)造器方法
  2. 執(zhí)行StatefulWidget的createState方法,來(lái)創(chuàng)建一個(gè)維護(hù)StatefulWidget的State對(duì)象
  3. 執(zhí)行State類的構(gòu)造方法(Constructor)來(lái)創(chuàng)建State對(duì)象;
  4. 執(zhí)行initState,我們通常會(huì)在這個(gè)方法中執(zhí)行一些數(shù)據(jù)初始化的操作
  5. 執(zhí)行build方法,渲染W(wǎng)idget
  6. 手動(dòng)調(diào)用setState方法,會(huì)根據(jù)最新的狀態(tài)(數(shù)據(jù))來(lái)重新調(diào)用build方法,構(gòu)建對(duì)應(yīng)的Widgets;
  7. 執(zhí)行didUpdateWidget方法是在當(dāng)父Widget觸發(fā)重建(rebuild)時(shí),系統(tǒng)會(huì)調(diào)用didUpdateWidget方法
  8. 當(dāng)前的Widget不再使用時(shí),會(huì)調(diào)用dispose進(jìn)行銷毀
  9. 在上面我們還看到了 didChangeDependencies方法
  • 這個(gè)方法是在 對(duì)象中依賴一些數(shù)據(jù)發(fā)生改變時(shí)會(huì)被調(diào)用

//創(chuàng)建一個(gè) JCHomeContent繼承StatefulWidget
class JCHomeContent extends StatefulWidget {

  JCHomeContent(){
    print("1.-----JCHomeContent的構(gòu)造器方法");
  }

  //創(chuàng)建一個(gè)State的子類來(lái)管來(lái)狀態(tài)
   @override
  State<StatefulWidget> createState() {
     print("2.-----JCHomeContent的createState方法");

    return _JCState();
  }
}


// 注意: 帶_的類或者成員變量,都只能在自己的模塊中使用,正在其他模塊不能被使用的,屬于自己私有

class _JCState extends State<JCHomeContent>{

   _JCState(){
     print("3.-----_JCState的搞構(gòu)造器方法");
   }

   @override
   void initState(){
     // 調(diào)用: 這里是必須調(diào)用super
     final TextStyle style = TextStyle();
     super.initState();

     print("4.-----_JCState的initState方法");
   }

   @override
   void didUpdateWidget(JCHomeContent oldWidget) {
     super.didUpdateWidget(oldWidget);
     print("didUpdateWidget");
   }

   @override
   void didChangeDependencies() {
     super.didChangeDependencies();
     print("調(diào)用_HYHomeContentState的didChangeDependencies方法");
   }



   int _count = 0;



  @override
  Widget build(BuildContext context) {
    print("5.-----_JCState的build方法");
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          RaisedButton(
            child: Text(
              "點(diǎn)擊+1",
              style: TextStyle(
                fontSize: 20,
                color: Colors.white
              ),
            ),
            color:Colors.pink ,
              onPressed: (){
                setState(() {
                  print("6.-----_JCState的setState方法");
                   this._count ++;
                });
              }
              ),
          SizedBox(height: 8,),
          Text(
            "當(dāng)前數(shù)字是:${this._count}",
            style: TextStyle(
              fontSize: 20
            ),
          ),
        ],
      ),
    );
  }
}






// 我們?cè)谏厦娴拇a中 添加上述的生命周期方法,打印結(jié)果
flutter: 1.-----JCHomeContent的構(gòu)造器方法
flutter: 2.-----JCHomeContent的createState方法
flutter: 3.-----_JCState的搞構(gòu)造器方法
flutter: 4.-----_JCState的initState方法
flutter: 調(diào)用_HYHomeContentState的didChangeDependencies方法
flutter: 5.-----_JCState的build方法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容