Flutter 之常見卻不清楚干嘛的 Key

官方解釋

/// A [Key] is an identifier for [Widget]s, [Element]s and [SemanticsNode]s.
///
/// A new widget will only be used to update an existing element if its key is
/// the same as the key of the current widget associated with the element.
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=kn0EOS-ZiIc}
///
/// Keys must be unique amongst the [Element]s with the same parent.
///
/// Subclasses of [Key] should either subclass [LocalKey] or [GlobalKey].
///
/// See also the discussion at [Widget.key].

重點提取:

我的使用場景之一

在了解 Flutter 相關(guān)動畫的時候,才第一次深入 Key 的理解(雖然以前經(jīng)常見??)
示例代碼如下:

class AnimatedSwitcherCounter extends StatefulWidget {
const AnimatedSwitcherCounter({Key key}) : super(key: key);

@override
_AnimatedSwitcherCounterState createState() =>
    _AnimatedSwitcherCounterState();
}

class _AnimatedSwitcherCounterState extends State<AnimatedSwitcherCounter> {
int _count = 0;

@override
Widget build(BuildContext context) {
  return Center(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        AnimatedSwitcher(
          duration: const Duration(milliseconds: 500),
          child: Text(
            '$_count',
            style: Theme.of(context).textTheme.headline4,
          ),
        ),
        RaisedButton(
          child: const Text(
            '+1',
          ),
          onPressed: () {
            setState(() {
              _count += 1;
            });
          },
        ),
      ],
    ),
  );
}
}

在點擊按鈕的時候并沒有相應的動畫效果,添加了相應的 key 之后才有

AnimatedSwitcher(
            duration: const Duration(milliseconds: 500),
            child: Text(
              '$_count',
              key: ValueKey<int>(_count),
              style: Theme.of(context).textTheme.headline4,
            ),
          ),

Widget 的渲染過程

Flutter 把視圖數(shù)據(jù)的組織和渲染抽象為三部分,即 Widget,Element 和 RenderObject

Widget:里面存儲的是布局、渲染、事件響應等有關(guān)視圖渲染的配置信息

Element: Widget 的一個實例化對象,承載了視圖構(gòu)建的上下文數(shù)據(jù),是連接結(jié)構(gòu)化的配置信息到完成最終渲染的橋梁,將 Widget 樹的變化做了抽象,能夠做到只將真正需要修改的部分同步到真實的 Render Object 樹中,最大程度地優(yōu)化了從結(jié)構(gòu)化的配置信息到完成最終渲染的過程

RenderObject:負責實現(xiàn)視圖的最終呈現(xiàn)

通俗的理解就是 Widget 樹、Element 樹、RenderObject 樹三者的配合最終完成了頁面的渲染

so,Key 發(fā)揮了什么作用呢?

如上示例中:
TextWidget 對應 TextElement,當頁面重新 build 的時候,發(fā)現(xiàn)有對應的 TextElement 就直接拿來用了,也就是他認為并不需要創(chuàng)建新的 Element,既然沒有發(fā)生 Switch 也就不會觸發(fā)動畫了,正如這個 Widget 的名字一樣 AnimatedSwitcher
當我們加入 Key (每個 Key 也不相同)的時候,每次都會創(chuàng)建新的 Element,so,每次都有發(fā)生 Switch 也就觸發(fā)了動畫了

Flutter 中都有哪些 Key (一圖勝千言)


之前畫 UML 的軟件出了問題,就拿 Xmind 畫吧,應該也很好看懂
Key 有兩子類:LocalKey 和 GlobalKey
LocalKey 有三子類:ValueKey、UniqueKey、ObjectKey

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

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