美文网首页
flutter GlobalKey、Key

flutter GlobalKey、Key

作者: liboxiang | 来源:发表于2020-12-18 14:17 被阅读0次

    Key

    局部key只会比较树中相同位置的widget,如children中index 为1的element不会复用到index为0的element位置,如果是children从后面添加元素,则前面的element可以复用。如果父element被重建,则子element一定也会被重建

    StatelessWidget 如果canUpdate,会调用widget的build方法。

    当新的widget并挂到树上时,会调用canUpdate方法,方法中有对key的比较

    @immutable
    abstract class Widget extends DiagnosticableTree {
      const Widget({ this.key });
      final Key key;
      ···
      static bool canUpdate(Widget oldWidget, Widget newWidget) {
        return oldWidget.runtimeType == newWidget.runtimeType
            && oldWidget.key == newWidget.key;
      }
    }
    

    GlobalKey

    GlobalKey其实就是缓存Element。缓存是通过GlobalKey类的静态Map _registry缓存的,当widget刷新的时候通过GlobalKey获取缓存的Element。

    Element类中GlobalKey相关代码如下:

    void mount(Element parent, dynamic newSlot) {
       ...
        if (key is GlobalKey) {
          key._register(this);
        }
        ...
      }
    
    @mustCallSuper
      void unmount() {
        ...
        final Key key = _widget.key;
        if (key is GlobalKey) {
          key._unregister(this);
        }
       ...
      }
    
    Element inflateWidget(Widget newWidget, dynamic newSlot) {
       ...
        if (key is GlobalKey) {
          final Element newChild = _retakeInactiveElement(key, newWidget);
          ...
        }
       ...
        return newChild;
      }
    
    Element _retakeInactiveElement(GlobalKey key, Widget ) {
      ...
        final Element element = key._currentElement;
        ...
        return element;
      }
    

    GlobalKey类主要代码如下:

    abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {
      static final Map<GlobalKey, Element> _registry = <GlobalKey, Element>{};
      void _register(Element element) {
        _registry[this] = element;
      }
    }
    
    void _unregister(Element element) {
        if (_registry[this] == element)
          _registry.remove(this);
      }
    
    Element get _currentElement => _registry[this];
    BuildContext get currentContext => _currentElement;
    Widget get currentWidget => _currentElement?.widget;
    T get currentState {
       ...
      }
    

    相关文章

      网友评论

          本文标题:flutter GlobalKey、Key

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