当你有一系列的 Widget 使用的是同样的类; 不给Flutter 传 Key的话,Flutter 有时候就会分不清楚他们的对应关系。尤其是widget 顺序发生改变的时候。这个是就需要我们通过 Key 来标识 Widget
widget并不是实际出现在屏幕上的东西, 它是由2部分组成:
Widget Tree: 生成(外观) 尺寸/形状/大小等
Element Tree: 在程序运行起来后, 管理Status状态信息
在Flutter的框架里,Widget是不可变的(一但建立后,在运行时就不可变). 但Status可以在运行的时候进行改变. 每次setStatus,就会通知Flutter创建一个新的Widget,把旧的替换掉.而不是去修改旧的Widget(Widget不可变). 在替换旧的Widget的时候,就会替换Widget Tree的内容
.
热重启时,修改Widget属性. 会检查一一对应的类型和Key. 如果Key对不上,Flutter会检查当前Widget,同一类型,同一层级Widget(父级,子级不会去搜索).
Flutter Key 的类型:
Local Key: 只对比同一级别的,速度快
ValueKey: 可以是 字符数值等等 值相等
ObjectKey: 引用地址
UniqueKey: 不需要参数
GlobalKey: 对于整个app
通过 key 找到对应的 widget,并调用方法
final widget = (_globalKey.currentContext!.findRenderObject() as RenderBox); print(widget.size); //获得组件尺寸 print(widget.localToGlobal(Offset.zero)); //位置信息
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; final _globalKey = GlobalKey(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Counter( key: _globalKey, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ) // This trailing comma makes auto-formatting nicer for build methods. ); } void _incrementCounter() { final widget = (_globalKey.currentContext!.findRenderObject() as RenderBox); print(widget.size); //获得组件尺寸 print(widget.localToGlobal(Offset.zero)); //位置信息 } } class Counter extends StatefulWidget { const Counter({Key? key}) : super(key: key); @override _CounterState createState() => _CounterState(); } class _CounterState extends State<Counter> { int _count = 0; @override Widget build(BuildContext context) { return RaisedButton( onPressed: () => setState(() { _count++; })); } }