官方解釋
/// 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].
重點提取:
- Key 是 Widget,Element 和 SemanticsNode 的標識符
- Key 的子類應該是 LocalKey 或 GlobalKey 的子類
- 視頻講解 https://www.youtube.com/watch?v=kn0EOS-ZiIc
我的使用場景之一
在了解 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