代码之家  ›  专栏  ›  技术社区  ›  KhoPhi

颤振切换到标签重新加载小工具并运行FutureBuilder

  •  14
  • KhoPhi  · 技术社区  · 7 年前

    问题:

    我有两个使用默认选项卡控制器的选项卡,如:

    widget build(build context context){
    返回默认选项卡控制器(
    长度:2,
    儿童:脚手架(
    抽屉:menu(),
    应用程序栏:应用程序栏(
    标题:容器(
    子:文本(“仪表板”),
    ),请
    底部:选项卡(
    选项卡:<小工具>。[
    集装箱(
    填充:边集。全部(8.0)
    子:文本(“交易”),
    ),请
    集装箱(
    填充:边集。全部(8.0)
    子:文本(“查看器”),
    ),请
    ],请
    ),请
    ),请
    正文:TabbarView(
    子项:<widget>。[
    dealList(),
    viewersPage(),
    ],请
    ),请
    ),请
    )(二)
    }
    }
    

    dealList()是一个statefulwidgetwhich is build like this:。

    widget build(build context context){
    返回FutureBuilder(
    未来:this.loadteals(),
    生成器:(BuildContext上下文,AsyncSnapshot快照){
    print('有错误:$snapshot.hasError');
    print('有数据:$快照.has data');
    print('快照数据:$快照.data');
    返回snapshot.connectionstate==connectionstate.done
    是吗?刷新指示器(
    OnRefresh:展示一些东西,
    子级:ListView.Builder(
    物理:const alwayscrollablescrollphysics(),
    itemcount:snapshot.data['deals'].长度,
    项生成器:(上下文、索引){
    final map deal=snapshot.data['deals'][索引];
    print('交易:$交易');
    返回_getdealeitem(deal,context);
    },请
    ),请
    )
    :居中(
    子级:CircularProgressIndicator(),
    )(二)
    },请
    )(二)
    }
    }
    

    有了上面的内容,每当我切换回dealelist()时,就会发生以下情况。tab:it reloads.

    有没有一种方法可以防止FutureBuilder重新运行一次?(该计划供用户使用刷新指示器重新加载。因此,更改选项卡不应触发任何操作,除非用户明确地这样做。)

    Widget build(BuildContext context) {
        return DefaultTabController(
          length: 2,
          child: Scaffold(
            drawer: Menu(),
            appBar: AppBar(
              title: Container(
                child: Text('Dashboard'),
              ),
              bottom: TabBar(
                tabs: <Widget>[
                  Container(
                    padding: EdgeInsets.all(8.0),
                    child: Text('Deals'),
                  ),
                  Container(
                    padding: EdgeInsets.all(8.0),
                    child: Text('Viewer'),
                  ),
                ],
              ),
            ),
            body: TabBarView(
              children: <Widget>[
                DealList(),
                ViewersPage(),
              ],
            ),
          ),
        );
      }
    }
    

    这个DealList()是一个StatefulWidget它是这样建造的:

    Widget build(BuildContext context) {
        return FutureBuilder(
          future: this.loadDeals(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            print('Has error: ${snapshot.hasError}');
            print('Has data: ${snapshot.hasData}');
            print('Snapshot data: ${snapshot.data}');
            return snapshot.connectionState == ConnectionState.done
                ? RefreshIndicator(
                    onRefresh: showSomething,
                    child: ListView.builder(
                      physics: const AlwaysScrollableScrollPhysics(),
                      itemCount: snapshot.data['deals'].length,
                      itemBuilder: (context, index) {
                        final Map deal = snapshot.data['deals'][index];
                        print('A Deal: ${deal}');
                        return _getDealItem(deal, context);
                      },
                    ),
                  )
                : Center(
                    child: CircularProgressIndicator(),
                  );
          },
        );
      }
    }
    

    在上面,每当我切换回释放列表()选项卡:它重新加载。

    Flutter

    有没有一种方法可以防止FutureBuilder重新运行一次?(该计划供用户使用刷新指示器重新加载。因此,除非用户明确地这样做,否则更改选项卡不应触发任何操作。)

    1 回复  |  直到 7 年前
        1
  •  37
  •   Gazihan Alankus Frank van Puffelen    7 年前

    TabController AutomaticKeepAliveClientMixin

    class _DealListState extends State<DealList> with AutomaticKeepAliveClientMixin<DealList> {
      @override
      bool get wantKeepAlive => true;
    
      @override
      Widget build(BuildContext context) {
        super.build(context); // need to call super method.
        return /* ... */
      }
    }
    

    FutureBuilder Future

    return FutureBuilder(
      future: this.loadDeals(), // Creates a new future on every build invocation.
      /* ... */
    );
    

    _loadingDeals setState

    Future<...> _loadingDeals;
    
    @override
    void initState() {
      _loadingDeals = loadDeals(); // only create the future once.
      super.initState();
    }
    
    @override
    Widget build(BuildContext context) {
      super.build(context); // because we use the keep alive mixin.
      return new FutureBuilder(future: _loadingDeals, /* ... */);
    }