美文网首页Android开发经验谈Flutter圈子Flutter中文社区
Flutter PageView组件怎样让子组件不会重复加载

Flutter PageView组件怎样让子组件不会重复加载

作者: dengyin2000 | 来源:发表于2019-07-30 22:17 被阅读4次

    在做一个美女相册flutter demo app的时候发现,每次切换页面的时候,里面的子页面(GridView widget)每次都会重新加载,就像下面这样:


    重新加载

    这样的体验肯定不行。经过一番调研后发现竟然还需要做蛮多事情的。

    先看看目前的实现:

    class BeautyListWidget extends StatefulWidget {
      final int tabIndex;
    
      const BeautyListWidget({Key key, this.tabIndex}) : super(key: key);
      @override
      _BeautyListWidgetState createState() => _BeautyListWidgetState();
    }
    
    class _BeautyListWidgetState extends State<BeautyListWidget> {
    
      @override
      Widget build(BuildContext context) {
        return FutureBuilder<List<Beauty>>(
          future: getBeautysForTab(widget.tabIndex),
          builder: (BuildContext context, AsyncSnapshot<List<Beauty>> snapshot) {
            var connectionState = snapshot.connectionState;
            if (connectionState == ConnectionState.done && snapshot.hasData) {
              var data = snapshot.data;
              return GridView.builder(
                gridDelegate:
                SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, mainAxisSpacing: 10, crossAxisSpacing: 10, ),
                itemBuilder: (BuildContext context, int index) {
                  return FadeInImage.assetNetwork(placeholder: 'assets/loading.png', image: data[index].thumbURL);
                },
                itemCount: data.length,
              );
            } else {
              return Center(
                child: CircularProgressIndicator(
                  backgroundColor: Colors.black,
                ),
              );
            }
          },
        );
      }
    }
    

    这个就是包含在PageView里面的子组件,很简单,通过FutureBuilder调一个接口返回数据后build一个GridView。很显然每次切换Tab的时候,应该是每次都进入了_BeautyListWidgetState的build方法,导致每次都会重新刷新。那要怎样才能做到加载后切换不再刷新呢?

    1、_BeautyListWidgetState实现AutomaticKeepAliveClientMixin

    需要实现wantKeepAlive方法(返回true),另外在build方法最前面需要 调用super.build(context);,如下:

    class _BeautyListWidgetState extends State<BeautyListWidget> with AutomaticKeepAliveClientMixin<BeautyListWidget> {
    
      @override
      Widget build(BuildContext context) {
        super.build(context);  //需要调用super
        return /* ... */
      }
    
      @override
      bool get wantKeepAlive => true;  //需要返回true
    }
    

    2、FutureBuilder中的future属性需要是同一个实例

    所以你需要在initState方法中创建这个Future。如下:

    class _BeautyListWidgetState extends State<BeautyListWidget> with AutomaticKeepAliveClientMixin<BeautyListWidget> {
    
      Future<List<Beauty>> _future; //保存这个实例
    
      @override
      Widget build(BuildContext context) {
        super.build(context);
        return FutureBuilder<List<Beauty>>(
          future: _future,  //每次build方法都是同一个实例
          builder: (BuildContext context, AsyncSnapshot<List<Beauty>> snapshot) {
              return /* ... */
            }
          },
        );
      }
    
      @override
      void initState() {
        super.initState();
        _future = getBeautysForTab(widget.tabIndex);  //创建这个实例
      }
    
      @override
      bool get wantKeepAlive => true;
    }
    
    

    好了。效果实现了。不过稍后还需要看看AutomaticKeepAliveClientMixin源码,看看它是如何做到的。


    保持状态

    Reference:https://stackoverflow.com/questions/51224420/flutter-switching-to-tab-reloads-widgets-and-runs-futurebuilder

    相关文章

      网友评论

        本文标题:Flutter PageView组件怎样让子组件不会重复加载

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