<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么 build 方法放在 State 中而不是在 StatefulWidget 中

          共 2770字,需瀏覽 6分鐘

           ·

          2021-01-17 14:44


          老孟導(dǎo)讀:此篇文章是生命周期相關(guān)文章的番外篇,在查看源碼的過程中發(fā)現(xiàn)了這一有趣的問題,歡迎大家一起探討。

          Flutter 中Stateful 組件的生命周期:http://laomengit.com/blog/20201227/Stateful%E7%BB%84%E4%BB%B6%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.html

          Flutter 中與平臺(tái)相關(guān)的生命周期:http://laomengit.com/blog/20201227/%E7%9B%B8%E5%85%B3%E5%B9%B3%E5%8F%B0%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F.html

          博客中還有更多精彩文章,也歡迎加入 Flutter 交流群。

          為什么 build 方法放在 State 中而不是在 StatefulWidget 中呢?其中前2點(diǎn)是源代碼的注釋中給出的原因,最后一點(diǎn)是我的一點(diǎn)個(gè)人理解。

          靈活性

          build 方法放在 State 中比放在 StatefulWidget 中更具靈活性,比如說,AnimatedWidgetStatefulWidget 的子類,AnimatedWidget 是一個(gè)抽象類,其中有一個(gè) Widget build(BuildContext context) 的抽象方法,此方法需要子類重寫,AnimatedWidget 源代碼如下:

          abstract?class?AnimatedWidget?extends?StatefulWidget?{
          ??...
          ??///?Override?this?method?to?build?widgets?that?depend?on?the?state?of?the
          ??///?listenable?(e.g.,?the?current?value?of?the?animation).
          ??@protected
          ??Widget?build(BuildContext?context);

          ??///?Subclasses?typically?do?not?override?this?method.
          ??@override
          ??_AnimatedState?createState()?=>?_AnimatedState();

          ??...
          }

          刪除了一些代碼,保留了重點(diǎn)代碼。

          試想一下,如果 build 方法放在 StatefulWidget 中,則 AnimatedWidget 中的 build 方法需要帶一個(gè) State 參數(shù),如下:

          abstract?class?AnimatedWidget?extends?StatefulWidget?{
          ??...
          ??///?Override?this?method?to?build?widgets?that?depend?on?the?state?of?the
          ??///?listenable?(e.g.,?the?current?value?of?the?animation).
          ??@protected
          ??Widget?build(BuildContext?context,?AnimatedState?state);

          ??///?Subclasses?typically?do?not?override?this?method.
          ??@override
          ??_AnimatedState?createState()?=>?_AnimatedState();

          ??...
          }

          但 AnimatedState 是內(nèi)部實(shí)現(xiàn),并不需要開放給外部(開發(fā)者),外部也不需要知道 AnimatedState 的內(nèi)部實(shí)現(xiàn)。

          閉包 this 指向異常

          假設(shè) build 方法在 StatefulWidget 中,StatefulWidget 的子類寫法如下:

          class?MyWidget?extends?StatefulWidget?{

          ??final?Color?color;

          ??@override
          ??Widget?build(BuildContext?context,?MyWidgetState?state)?{
          ????print('${this.color}');
          ????return?Container();
          ??}
          }

          此時(shí)的 this 指向的是 MyWidget 的實(shí)例,然后父組件改變顏色,重新構(gòu)建 MyWidget 組件,前一個(gè) MyWidget 的實(shí)例中的 this 依然指向前一個(gè) MyWidget 的實(shí)例,顏色并未發(fā)生變化。

          如果 build 方法在 State 中,代碼如下:

          class?MyWidget?extends?StatefulWidget?{
          ??final?Color?color;

          ??const?MyWidget({Key?key,?this.color})?:?super(key:?key);
          ??
          ??@override
          ??_MyWidgetState?createState()?=>?_MyWidgetState();
          }

          class?_MyWidgetState?extends?State<MyWidget>?{
          ??@override
          ??Widget?build(BuildContext?context)?{
          ????print('${widget.color}');
          ????return?Container();
          ??}
          }

          同樣,父組件改變顏色,重新構(gòu)建 MyWidget 組件,此時(shí)框架更新了 State 對(duì)象的 widget 屬性的引用,新的 MyWidget 實(shí)例和 $ {widget.color} 將顯示綠色。

          性能

          有狀態(tài)的組件包含StatefulWidget 和 State,當(dāng)有狀態(tài)組件的配置發(fā)生更改時(shí),StatefulWidget 將會(huì)被丟棄并重建,而 State 不會(huì)重建,框架會(huì)更新 State 對(duì)象中 widget 的引用,這極大的減輕了系統(tǒng)重建有狀態(tài)組件的工作。

          此方式對(duì)動(dòng)畫來說極為重要,由于 State 不會(huì)被重建,保留了前面的狀態(tài),不斷的根據(jù)前一個(gè)狀態(tài)計(jì)算下一個(gè)狀態(tài)并重建其widget,達(dá)到動(dòng)畫的效果。


          你可能還喜歡


          關(guān)注「老孟Flutter」
          讓你每天進(jìn)步一點(diǎn)點(diǎn)


          瀏覽 61
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人三级AV在线 | 亚洲欧洲无码高清 | 蜜芽av最新网址 蜜芽欧洲无码精品 | 热国产中文网 | 天堂男人在线视频 |