官方解释
/// 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 相关动画的时候,才第一次深入 Key 的理解(虽然以前经常见😓)
示例代码如下:
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 把视图数据的组织和渲染抽象为三部分,即 Widget,Element 和 RenderObject
Widget:里面存储的是布局、渲染、事件响应等有关视图渲染的配置信息
Element: Widget 的一个实例化对象,承载了视图构建的上下文数据,是连接结构化的配置信息到完成最终渲染的桥梁,将 Widget 树的变化做了抽象,能够做到只将真正需要修改的部分同步到真实的 Render Object 树中,最大程度地优化了从结构化的配置信息到完成最终渲染的过程
RenderObject:负责实现视图的最终呈现
通俗的理解就是 Widget 树、Element 树、RenderObject 树三者的配合最终完成了页面的渲染
so,Key 发挥了什么作用呢?
如上示例中:
TextWidget 对应 TextElement,当页面重新 build 的时候,发现有对应的 TextElement 就直接拿来用了,也就是他认为并不需要创建新的 Element,既然没有发生 Switch 也就不会触发动画了,正如这个 Widget 的名字一样 AnimatedSwitcher
当我们加入 Key (每个 Key 也不相同)的时候,每次都会创建新的 Element,so,每次都有发生 Switch 也就触发了动画了
Flutter 中都有哪些 Key (一图胜千言)
之前画 UML 的软件出了问题,就拿 Xmind 画吧,应该也很好看懂
Key 有两子类:LocalKey 和 GlobalKey
LocalKey 有三子类:ValueKey、UniqueKey、ObjectKey