美文网首页
第十四章:Widget的key原理和使用

第十四章:Widget的key原理和使用

作者: Mr姜饼 | 来源:发表于2021-05-24 16:35 被阅读0次

分析key的原理,渲染机制

问题引导:首先我们先来看以下的一个demo例子:
import 'package:flutter/material.dart';
import 'dart:math';
//key本身是一个抽象类   flutter的增量更新,会根据elelment和widget之间的key做对比,来判别是否更新
//ValueKey、ObjectKey、UniqueKey

class KeyDemo extends StatefulWidget {
  @override
  _State createState() => _State();
}

class _State extends State<KeyDemo> {
   List<Widget> _widgetss = [
    JItem(text: '111',),
     JItem(text: '222',),
     JItem(text: '333',),
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          SizedBox(height: 100,),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: _widgetss,
          ),
          SizedBox(height: 100,),
          FloatingActionButton(onPressed: (){
            setState(() {
              _widgetss.removeAt(0);
            });
          }),
        ],
      ),
    );
  }
}

class JItem extends StatefulWidget {
  final String text;
  JItem({
   this.text,
  });
  @override
  _JItemState createState() => _JItemState();
}

class _JItemState extends State<JItem> {

  final _color = Color.fromRGBO(Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1);
  @override
  Widget build(BuildContext context) {
    return  Container(color: _color,child: Text('1111'),width: 100,height: 100,);
  }
}






run

42.png

点击一次按钮:思考为什么粉色的方块消息了呢,而不是褐色方块消息呢?????

43.png

点击一次按钮:思考为什么褐色的方块消息了呢,而不是紫色方块消息呢?????

44.png
原理探究:渲染机制

Widget树对应着element树,当widget树中的第一个widget消失的时候,那么element中的第一个将会去查找widget树中的第二个widget,当判断类型相同且key值一样时,这时候,就会产生element重用的机制,即第二个widget重用了第一个element的属性,即颜色色值,当然widget中的data发生了改变,所以产生了即将显示的widget重用了本该消失的element。而最后一个element被抛弃了

  static bool canUpdate(Widget oldWidget, Widget newWidget) {
    return oldWidget.runtimeType == newWidget.runtimeType
        && oldWidget.key == newWidget.key;
  }
解决思路一:

我们将state中的属性值放到widget中,即element失去持有,即使重用也没关系。但此方法并不可取,

class JItem extends StatefulWidget {
  final String text;
  final _color = Color.fromRGBO(Random().nextInt(256), Random().nextInt(256), Random().nextInt(256), 1);
  JItem({
   this.text,
  });
  @override
  _JItemState createState() => _JItemState();
}

class _JItemState extends State<JItem> {
  
  @override
  Widget build(BuildContext context) {
    return  Container(color: widget._color,child: Text('1111'),width: 100,height: 100,);
  }
}
解决思路一:巧用key,

通常我们会用widget设置key来建立与element的连接,这样就不会导致element的重用

  • ValueKey:适用于比较单一的区别判断,
class JItem extends StatefulWidget {
  final String text;
  JItem({this.text,Key key}) : super(key : key);
  @override
  _JItemState createState() => _JItemState();
}
List<Widget> _widgetss = [
    JItem(text: '111',key: ValueKey('111'),),
     JItem(text: '222',key: ValueKey('222'),),
     JItem(text: '333',key: ValueKey('333'),),
  ];
  • ObjectKey:适用于组合类型的区别判断,
  • UniqueKey: 唯一key
  • PageStorageKey :这是一个很特殊的key,它保存了用户滚动的位置,这样app可以保存用户滚动的位置给下次用户打开的时候直接到上次滚动的位置。
  • GlobalKey:可以在app的任何地方更换父widget而不会丢失状态、它可以用来从完全不同的widget树里面访问数据
class _State extends State<KeyDemo> {
  final GlobalKey<_JItemState>  _globalKey = GlobalKey();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          SizedBox(height: 100,),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children:[
              JItem(text: '111',key: _globalKey,),
            ],
          ),
          SizedBox(height: 100,),
          FloatingActionButton(onPressed: (){
            setState(() {
              _globalKey.currentState.setState(() {
                _globalKey.currentState._color = Colors.orange;
              });
            });
          }),
        ],
      ),
    );
  }
}

相关文章

  • 第十四章:Widget的key原理和使用

    分析key的原理,渲染机制 问题引导:首先我们先来看以下的一个demo例子: run 点击一次按钮:思考为什么粉色...

  • flutter随手记

    1 Widget Key的左右和GlobalKey与普通Key的区别Controls how one widget...

  • StatefulWidget刷新数据问题

    刷新数据setState,如果不设置key,子widget不会执行initState。解决方案使用widget获取...

  • Flutter知识集

    BuildContext Widget的绘制 事件传递机制 手势 key的作用 框架原理 Builder里的con...

  • Flutter 动画入门

    官方动画介绍 让Widget动起来 1.使用Animation 原理类似于Android的属性动画,和Widget...

  • The Key of Widget in Flutter

    The Key of Widget in Flutter 当我们刚开始使用Flutter,我们在继承Statele...

  • Flutter 中 key 的原理及作用

    Key 的原理 如图 1 所示,当我们生成一个 Widget 树的时候也会对应生成 Element 树,Widge...

  • iOS 字典的实现原理

    一、NSDictionary使用原理 1.NSDictionary(字典)是使用hash表来实现key和value...

  • hash表原理

    一、NSDictionary使用原理 1.NSDictionary(字典)是使用hash表来实现key和value...

  • iOS 字典的实现原理

    一、NSDictionary使用原理1.NSDictionary(字典)是使用hash表来实现key和value之...

网友评论

      本文标题:第十四章:Widget的key原理和使用

      本文链接:https://www.haomeiwen.com/subject/nfxxsltx.html