首页 > 其他分享 >28、Flutter Key详解

28、Flutter Key详解

时间:2024-01-10 11:11:34浏览次数:35  
标签:Widget const Key 28 override GlobalKey key 组件 Flutter

在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

相关文章

  • flutter TextFormField
    TextFormField(maxLength:20,controller:controller.shippernameController,decoration:InputDecoration(counterText:'',//计数器的显示border:InputBorder.none,fillColor:Colors.white,filled:true,is......
  • 两个Mysql唯一索引的交换: 避免重复索引 Duplicate entry '3' for key 'priority_UNIQ
    需求我做了一个排行榜,但是主键是pid,不是排名,排名作为唯一索引,两个人排名交换,只需要交换排名唯一索引值即可.但是直接单独更新提示错误:Duplicateentry'3'forkey'priority_UNIQUE'方法本来希望可以在一条SQL语句中交换两个唯一索引值,但是发现这是不可能的,因为值......
  • mit6.828 - lab5笔记(上)
    文件系统结构unix的文件系统相关知识unix将可用的磁盘空间划分为两种主要类型的区域:inode区域和数据区域。unix为每个文件分配一个inode,其中保存文件的关键元数据,如文件的stat属性和指向文件数据块的指针。数据区域中的空间会被分成大小相同的数据块(就像内存管理中的分页)。数......
  • flutter MaterialApp介绍
    MaterialApp 是Flutter中常用的一个widget,它是构建基于 MaterialDesign 风格应用的根组件,主要负责各种全局状态的管理以及定义应用程序的主题样式等。voidmain(){runApp(MaterialApp(title:"flutterAPP___test",theme:ThemeData(primarySw......
  • GB28181视频汇聚平台EasyCVR级联后,部分通道视频无法播放是什么原因?
    国标GB28181安防监控EasyCVR平台能通过标准接口与标准协议与第三方平台级联,实现视频资源的互通共享、共用,EasyCVR既能作为上级平台与下级级联,也能作为下级平台级联到上级监管平台。有用户反馈,下级平台级联到EasyCVR平台后,有的通道能正常播放,但是大部分通道无法播放,于是请求我们排查......
  • MybatisPlus查询返回Map,其中一个字段为key,另一个字段或者实体为value
    一、需求背景项目中有一些基础数据,以国家为例,字段有国家代码、国家名称、国家面积等等信息。在项目中其他位置需要验证并使用国家数据,比如商品每次批量保存时,只能拿到国家的编码,你需要校验国家是否合法,并把国家的名称面积等字段放到商品表(案例可能不恰当,为了表达业务场景)二、遇到的......
  • STM32 ADS1284的开发学习
    1设备功能模式同步(SYNCPIN和SYNC命令)ADS1284可以同步到外部事件,如果同时施加同步脉冲,还可以将多个ADS1284设备同步在一起。该ADS1284有两种同步方法:SYNC输入引脚和SYNC命令。此外,还有两种同步模式:脉冲同步和连续同步。在脉冲同步模式下,ADS1284在每个同步事件时无条件同步......
  • 火车 行程轨迹 K936 K536 k2286 K474 K284
    K936次列车广东省湖南省湖北省K474次列车是一趟昆明开往北 K474次列车是一趟昆明开往北k2286 k228611月3日23:14 致远 :焦作火车站和高铁站是一个站,焦作只有一个火车站,称为焦作站。焦作站位于焦作市解放区站前路129号,是中国铁路郑州局集团有限公......
  • LiveGBS流媒体平台GB/T28181常见问题-国标编号是什么设备编号和通道国标编号标记唯一
    LiveGBS国标GB28181中国标编号是什么设备编号和通道国标编号标记唯一的摄像头|视频|镜头通道1、什么是国标编号?2、国标设备ID和通道ID3、ID统一编码规则4、搭建GB28181视频直播平台1、什么是国标编号?国标GB28181对接过程中,可能有的小伙伴会疑惑编号的问题。比如设备ID、视频通道......
  • LiveGBS流媒体平台GB/T28181功能-用户管理通道权限管理关联通道支持只看已选只看未选
    LiveGBS功能用户管理通道权限管理关联通道支持只看已选只看未选添加用户备注角色1、用户管理2、添加用户3、关联通道3.1、只看已选3.2、只看未选4、自定义角色5、搭建GB28181视频直播平台1、用户管理LiveGBS支持用户管理,添加用户,及配置相关用户权限,可以添加管理员、操作员观众2、......