问题是:

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

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(),
              );
      },
    );
  }
}

根据以上内容,每当我切换回DealList()选项卡时,都会发生这样的情况:它会重新加载.

FIFTER

有没有办法防止FutureBuilder在运行一次后重新运行?(计划是让用户使用刷新指示器重新加载.因此,除非用户明确更改选项卡,否则不会触发任何操作.)

推荐答案

这里有两个问题,第一个:

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- 如果您提供一个新的FutureFutureBuilder,它无法判断结果是否会与上次相同,因此它必须重建.(请记住,Flutter 最多可以在一帧中调用Build方法一次).

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

相反,您希望将future 分配给initState中State类上的成员,然后将该值传递给FutureBuilder.可确保后续重建的future 是相同的.如果要强制州重新加载交易,您始终可以创建重新分配_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, /* ... */);
}

Flutter相关问答推荐

为什么Riverpod生成器在这种情况下不生成AsyncNotiator?

在Android Studio的新用户界面中未找到热重新加载

CMakeLists.txt处的CMake错误:3(项目)找不到指定的Visual Studio实例

如何处理Flutter Riverpod异步通知器中的状态和数据库

Flutter 应用程序中的Firebase实时数据库中的orderByChild()不适用于我

Flutter :执行com.android.build.gradle.internal.tasks.MergeNativeLibsTask$MergeNativeLibsTaskWorkAction时出现故障

在Flutter 小部件测试中找不到框中的AssetImage装饰

Flutter Xcode 15 错误(Xcode):DT_TOOLCHAIN_DIR 无法用于判断 LIBRARY_SEARCH_PATHS

Select 文本时如何更改 Flutter 中的光标 colored颜色 ?

Flutter - firebase_auth_web 5.4.0 依赖于 intl ^0.17.0 但我必须使用更高版本 (intl ^0.18.0)

输入处于活动状态时如何设置文本字段标签的样式?

flutter 中 // 和 /// 有什么区别

状况不佳 - Cubit

flutter - 无法解析 JSON 消息:文档为空

SfCircularChart 周围的额外间距

Flutter 中父容器顶部的 Gridview 间距额外区域

在 flutter 中使用 StreamBuilder 在文本字段中键入时显示过滤记录

Flutter 本地通知在最新版本中不起作用

解密 Modulr 安全令牌

在另一个页面编辑数据后更新 Flutter 页面的惯用方法?