当你有一系列的 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++;
}));
}
}
|