官方解釋
/// 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].
重點(diǎn)提取:
- Key 是 Widget拴孤,Element 和 SemanticsNode 的標(biāo)識符
- Key 的子類應(yīng)該是 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;
});
},
),
],
),
);
}
}
在點(diǎn)擊按鈕的時候并沒有相應(yīng)的動畫效果张肾,添加了相應(yīng)的 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:里面存儲的是布局桨昙、渲染讲弄、事件響應(yīng)等有關(guān)視圖渲染的配置信息
Element: Widget 的一個實(shí)例化對象措左,承載了視圖構(gòu)建的上下文數(shù)據(jù),是連接結(jié)構(gòu)化的配置信息到完成最終渲染的橋梁避除,將 Widget 樹的變化做了抽象怎披,能夠做到只將真正需要修改的部分同步到真實(shí)的 Render Object 樹中胸嘁,最大程度地優(yōu)化了從結(jié)構(gòu)化的配置信息到完成最終渲染的過程
RenderObject:負(fù)責(zé)實(shí)現(xiàn)視圖的最終呈現(xiàn)
通俗的理解就是 Widget 樹、Element 樹凉逛、RenderObject 樹三者的配合最終完成了頁面的渲染
so性宏,Key 發(fā)揮了什么作用呢?
如上示例中:
TextWidget 對應(yīng) TextElement状飞,當(dāng)頁面重新 build 的時候毫胜,發(fā)現(xiàn)有對應(yīng)的 TextElement 就直接拿來用了,也就是他認(rèn)為并不需要創(chuàng)建新的 Element昔瞧,既然沒有發(fā)生 Switch 也就不會觸發(fā)動畫了指蚁,正如這個 Widget 的名字一樣 AnimatedSwitcher
當(dāng)我們加入 Key (每個 Key 也不相同)的時候,每次都會創(chuàng)建新的 Element自晰,so凝化,每次都有發(fā)生 Switch 也就觸發(fā)了動畫了
Flutter 中都有哪些 Key (一圖勝千言)
之前畫 UML 的軟件出了問題,就拿 Xmind 畫吧酬荞,應(yīng)該也很好看懂
Key 有兩子類:LocalKey 和 GlobalKey
LocalKey 有三子類:ValueKey搓劫、UniqueKey、ObjectKey