在Flutter中,Key是不能重复使用的,所以Key一般用来做唯一标识。组件在更新的时候,其状态的保 存主要是通过判断组件的类型或者key值是否一致。因此,当各组件的类型不同的时候,类型已经足够 用来区分不同的组件了,此时我们可以不必使用key。但是如果同时存在多个同一类型的控件的时候, 此时类型已经无法作为区分的条件了,我们就需要使用到key。
Flutter key:LocalKey(局部)、GlobalKey(全局)
在Flutter中,Key是不能重复使用的,所以Key一般用来做唯一标识。组件在更新的时候,其状态的保 存主要是通过判断组件的类型或者key值是否一致。因此,当各组件的类型不同的时候,类型已经足够 用来区分不同的组件了,此时我们可以不必使用key。但是如果同时存在多个同一类型的控件的时候, 此时类型已经无法作为区分的条件了,我们就需要使用到key。 Flutter key子类包含 LocalKey 和 GlobalKey 。局部键(LocalKey):ValueKey、ObjectKey、UniqueKey
全局键(GlobalKey): GlobalKey、GlobalObjectKey
ValueKey (值key)
把一个值作为key ,UniqueKey(唯一key)程序生成唯一的Key,当我们不知道 如何指定ValueKey的时候就可以使用UniqueKey,ObjectKey(对象key)把一个对象实例作为key。GlobalKey(全局key)
GlobalObjectKey(全局Objec key,和ObjectKey有点类似)LocalKey
LocalKey只在当前的组件树有效GlobalKey的使用
GlobalKey就类似于全局变量class MyKey extends StatelessWidget { const MyKey({super.key}); @override Widget build(BuildContext context) { print(MediaQuery.of(context).orientation); //监听屏幕方向(横竖) return 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(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List<Widget> list = []; final GlobalKey _key1 = GlobalKey(); final GlobalKey _key2 = GlobalKey(); final GlobalKey _key3 = GlobalKey(); @override void initState() { // TODO: implement initState super.initState(); list = [ Box( key: _key1, color: Colors.blue, ), Box( key: _key2, color: Colors.red, ), Box( key: _key3, color: Colors.orange, ) ]; } @override Widget build(BuildContext context) { print(MediaQuery.of(context).orientation); return Scaffold( floatingActionButton: FloatingActionButton( onPressed: () { setState(() { list.shuffle(); //打乱list的顺序 }); }, child: const Icon(Icons.refresh), ), appBar: AppBar( title: const Text('Title'), ), body: Center( child: MediaQuery.of(context).orientation == Orientation.portrait ? Column( mainAxisAlignment: MainAxisAlignment.center, children: list, ) : Row( mainAxisAlignment: MainAxisAlignment.center, children: list, ), ), ); } } class Box extends StatefulWidget { Color color; Box({super.key, required this.color}); @override State<Box> createState() => _BoxState(); } class _BoxState extends State<Box> { int _count = 0; @override Widget build(BuildContext context) { return SizedBox( height: 100, width: 100, child: ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(widget.color)), onPressed: () { setState(() { _count++; }); }, child: Center( child: Text("$_count"), ), ), ); } }
GlobalKey 获取子组件
globalKey.currentState 可以获取子组件的状态,执行子组件的方法,globalKey.currentWidget可以获 取子组件的属性,_globalKey.currentContext!.findRenderObject()可以获取渲染的属性。import 'package:flutter/material.dart'; class MyKey extends StatelessWidget { const MyKey({super.key}); @override Widget build(BuildContext context) { return 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 HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { final GlobalKey _globalKey = GlobalKey(); @override Widget build(BuildContext context) { return Scaffold( floatingActionButton: FloatingActionButton( child: const Icon(Icons.add), onPressed: () { //1、获取子组件的状态 调用子组件的属性 var state = (_globalKey.currentState as _BoxState); setState(() { state._count++; }); state.run(); //调用子部件的run方法 //2、获取子组件的属性(了解) var box = (_globalKey.currentWidget as Box); print(box.color); //3、获取子组件渲染的属性(了解) var renderBox = (_globalKey.currentContext!.findRenderObject() as RenderBox); print(renderBox.size); }, ), appBar: AppBar( title: const Text('Title'), ), body: Center( child: Box( key: _globalKey, color: Colors.red, ), ), ); } } class Box extends StatefulWidget { final Color color; const Box({Key? key, required this.color}) : super(key: key); @override State<Box> createState() => _BoxState(); } class _BoxState extends State<Box> { int _count = 0; run() { print("我是子部件的run方法"); } @override Widget build(BuildContext context) { return SizedBox( height: 100, width: 100, child: ElevatedButton( style: ButtonStyle( backgroundColor: MaterialStateProperty.all(widget.color)), onPressed: () { setState(() { _count++; }); }, child: Center( child: Text("$_count"), ), ), ); } }
Widget Tree、Element Tree 和 RenderObject Tree
Flutter应用是由是Widget Tree、Element Tree 和 RenderObject Tree组成 Widget可以理解成一个类,Element可以理解成Widget的实例,Widget与Element的关系可以是一对 多,一份配置可以创造多个Element实例 默认情况下面,当Flutter同一个 Widget的大小,顺序变化的时候,FLutter不会改变Widget的state。标签:Widget,const,Key,28,override,GlobalKey,key,组件,Flutter From: https://www.cnblogs.com/xbinbin/p/17951245