You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

混用GetBuilder()与FutureBuilder()时UI不刷新问题排查

点击解除屏蔽后UI不刷新的原因及修复方案

问题根源

  • Future仅初始化一次:你的userDoc是在控制器onInit阶段调用Firestore的get()方法获取的一次性Future,get()只会拉取一次当前数据,后续后端数据更新后,这个Future存储的仍是旧快照。
  • refresh方法未更新数据源:控制器里的refresh()仅调用update()触发GetBuilder重建,但没有重新请求Firestore的最新数据,因此FutureBuilder拿到的依旧是旧数据,UI自然不会刷新。

修复步骤

1. 修改BlockedAccountController

在refresh方法中重新获取Firestore数据,更新userDoc的引用:

class BlockedAccountController extends GetxController {
  late Future<DocumentSnapshot<Map<String, dynamic>>> userDoc;

  // 封装获取数据的方法
  void fetchBlockedUsers() {
    userDoc = FirebaseFirestore.instance
        .collection("users")
        .doc(currentusername)
        .get();
  }

  void refresh() {
    fetchBlockedUsers(); // 重新拉取最新数据
    update(); // 通知GetBuilder重建UI
  }

  @override
  void onInit() {
    fetchBlockedUsers(); // 初始化时获取数据
    super.onInit();
  }
}

2. 可选优化:改用StreamBuilder实现实时同步

如果希望UI自动响应Firestore数据变化,无需手动调用refresh,可以将Future替换为实时流:

控制器修改

class BlockedAccountController extends GetxController {
  late Stream<DocumentSnapshot<Map<String, dynamic>>> userStream;

  void fetchBlockedUsers() {
    userStream = FirebaseFirestore.instance
        .collection("users")
        .doc(currentusername)
        .snapshots(); // 用snapshots()获取实时数据流
  }

  @override
  void onInit() {
    fetchBlockedUsers();
    super.onInit();
  }
}

UI部分替换为StreamBuilder

GetBuilder<BlockedAccountController>(
  builder: (controller) {
    return StreamBuilder(
        stream: controller.userStream,
        builder: ((context, snapshot) {
          if (snapshot.hasData && snapshot.data!.exists) {
            final blockUsers = snapshot.data!["blockusers"] ?? [];
            return ListView.builder(
              itemCount: blockUsers.length,
              shrinkWrap: true,
              itemBuilder: (context, index) {
                return Container(
                  color: mainappColor,
                  height: 50,
                  width: double.infinity,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Padding(
                        padding: const EdgeInsets.only(left: 8.0),
                        child: Text(
                          blockUsers[index],
                          style: TextStyle(fontSize: 20),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(right: 8.0),
                        child: InkWell(
                          onTap: () async {
                            await unblockAccount(currentusername, blockUsers[index]);
                            // 使用Stream时无需手动refresh,数据会自动同步到UI
                          },
                          child: Container(
                            decoration: BoxDecoration(
                                color: Colors.purple,
                                borderRadius: BorderRadius.all(
                                    Radius.circular(5))),
                            alignment: Alignment.center,
                            width: 80,
                            height: 40,
                            child: Text("unblock".tr),
                          ),
                        ),
                      )
                    ],
                  ),
                );
              },
            );
          } else {
            return Text("");
          }
        }));
  },
)

内容的提问来源于stack exchange,提问作者BlaCK _ WolF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 04:37:38