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

在做一个美女相册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 {

  @override
  Widget build(BuildContext context) {
    return FutureBuilder>(
      future: getBeautysForTab(widget.tabIndex),
      builder: (BuildContext context, AsyncSnapshot> 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 with AutomaticKeepAliveClientMixin {

  @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 with AutomaticKeepAliveClientMixin {

  Future> _future; //保存这个实例

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return FutureBuilder>(
      future: _future,  //每次build方法都是同一个实例
      builder: (BuildContext context, AsyncSnapshot> 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组件怎样让子组件不会重复加载)