Key的原理

1.Widget

abstract class Widget extends DiagnosticableTree {

    static bool canUpdate(Widget oldWidget, Widget newWidget) {

        return oldWidget.runtimeType == newWidget.runtimeType

              && oldWidget.key == newWidget.key;

    }

}

Widget拥有canUpdate 方法

abstract class Element {

    @override

    Widget get widget =>_widget;

}

Element拥有 widget属性

2.ValueKey 使用

LocalKey使用

List_fitems = [

    SflDemo('111', ),

    SflDemo('222', ),

    SflDemo('333', ),

];

添加_fitems组件数组

Scaffold(

body:Row(

    mainAxisAlignment: MainAxisAlignment.center,

    children:_fitems,

),

floatingActionButton :FloatingActionButton(

    child:Icon(Icons.add),

    onPressed: (){

        setState(() {

            _fitems.removeAt(0);

        });

    },

    ),

)

SflDemo组件

class SflDemo extends StatefulWidget {

    final String title;

    const SflDemo(this.title, {Key? key}):super(key: key);

    @override

      _SflDemoState createState() =>_SflDemoState();

}

class _SflDemoState extends State {

    Color?_color;

    @override

      void initState() {

        super.initState();

        _color =Color.fromRGBO(Random().nextInt(256),Random().nextInt(256),Random().nextInt(256),1);

    }

    @override    

      Widget build(BuildContext context) {

        return Container(

            alignment:Alignment(0,0),

            width:100,

            height:100,

            color:_color,

                child:Text(widget.title),

    );

}

}

页面SflDemo组件颜色重用

解析


SflDemo组件颜色重用示意图

解决方法

static bool canUpdate(Widget oldWidget, Widget newWidget) {

        return oldWidget.runtimeType == newWidget.runtimeType

              && oldWidget.key == newWidget.key;

    }

canUpdate决定 Widget的类型 和 Key,

在SflDemo构造方法中添加Key,解决问题

List_fitems = [

    SflDemo('111', key:const ValueKey('1'),),

    SflDemo('222', key:const ValueKey('2'),),

    SflDemo('333', key:const ValueKey('3'),),

];

GlobalKey使用

需求改变子组件的数值,通过GlobalKey实现

class _GlobalKeyDemoStateextends State {

    GlobalKey<_GlobalKeyItemState>_globalKey =GlobalKey(); // 给_GlobalKeyItemState打上标识

    @override

      Widget build(BuildContext context) {

        return Scaffold(

            body:GlobalKeyItem(key:_globalKey,), // GlobalKeyItem组件传个globalKey

            floatingActionButton :FloatingActionButton(

                child:Icon(Icons.add),

                onPressed: (){

                    // 使用globalKey 操作子组件 GlobalKeyItem

                    _globalKey.currentState?.setState(() {//子组件 GlobalKeyItem 刷新

                        _globalKey.currentState?.count++; // 获取子组件 GlobalKeyItem 的count属性

                    });

            },

    ),

    );

    }

}

class GlobalKeyItem extends StatefulWidget {

    GlobalKeyItem({Key? key}):super(key: key);

    @override

      _GlobalKeyItemState createState() =>_GlobalKeyItemState();    

}

class _GlobalKeyItemStateextends State {

    int count =0;

    @override

      Widget build(BuildContext context) {

            return Container(

            child:Text('count: $count'),

    );

    }

}

3。总结

ValueKey:widget 的标识,在Element树中Element是否可以重用,起决定作用

GlobalKey:在祖组件中的标识, 可以在父组件以及祖先组件中,通过GlobalKey获得子组件

你可能感兴趣的:(Key的原理)