美文网首页Flutter面试
AutomaticKeepAliveClientMixin 基本

AutomaticKeepAliveClientMixin 基本

作者: 小吉快跑呀 | 来源:发表于2019-07-11 09:37 被阅读0次

    了解了keepalive的大致过程,在项目中,"我的"页内部是一个由tabbar和pageview联动的widget,选中tab时会在widget中保存一个value表示当前位置,但是,如果不做任何处理,当从"我的"切换到其他页面比如"首页"时,"我的"页的widget将会被移出widget tree和销毁,所以重新切回"我的"页时,选中的tab变回默认,但这不是我们想要的表现。flutter提供了一种当widget从tree中remove后仍然保存相关变量的方式——AutomaticKeepAliveClientMixin。

    在state后面加上with AutomaticKeepAliveClientMixin,并重写wantKeepAlive的getter,这样任何情况下这个widget都会被保存。

    class _MineTabState extends State<MineTab> with AutomaticKeepAliveClientMixin {
      @override
      bool get wantKeepAlive => true;
    }
    

    他的实现原理大致如下,AutomaticKeepAliveClientMixin内部有一个_ensureKeepAlive方法,内部会向上发送一个KeepAliveNotification通知,当initState、updateState以及deactivate时都会发送这个通知:

    mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> {
      KeepAliveHandle _keepAliveHandle;
    
      void _ensureKeepAlive() {
        assert(_keepAliveHandle == null);
        _keepAliveHandle = KeepAliveHandle();
        KeepAliveNotification(_keepAliveHandle).dispatch(context);
      }
    }
    

    当上级中有一个widget是AutomaticKeepAlive类型时,内部的NotificationListener会接受这种通知,然后通过childe 的 Element去保存该widget,但是从表现上看,假如AutomaticKeepAlive和发送通知的widget中间隔了几层widget的话,中间的几层widget也会跟着发送通知的widget一起被保存下来。

    class _AutomaticKeepAliveState extends State<AutomaticKeepAlive> {
      void _updateChild() {
        _child = NotificationListener<KeepAliveNotification>(
          onNotification: _addClient,
          child: widget.child,
        );
      }
    
    

    再继续往上查看源码,可以看到,pageview内部是有一个AutomaticKeepAlive类型的widget去包裹child的,这可能就是pageview可以快速支持keepalive的原因了,flutter中似乎所有的可滚动widget都默认开启了keepalive,这应该是滚动的一种优化,减少滚动中item的大量重建。

    相关文章

      网友评论

        本文标题:AutomaticKeepAliveClientMixin 基本

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