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

Flutter GetX:热重启后页面变量不更新,首次启动正常?

问题解决方法

核心问题分析

热重启后页面一直显示加载圈的原因主要有两个:

  1. build方法重复触发数据请求:页面的build会在热重启时重新执行,每次执行都会调用getData(),把_isSuccess重置为false,即使后续会改为true,但重复的请求会导致UI一直停留在加载状态。
  2. GetBuilder与RxBool的搭配问题:你用了响应式的RxBool,却用需要手动调用update()的GetBuilder,热重启时可能出现手动更新不及时或关联失效的情况。

具体修复方案

方案1:避免在build中调用数据请求

build方法会被频繁触发(热重启、屏幕旋转、父组件重建等),绝对不能在这里调用getData()。把请求移到页面初始化逻辑中:

如果是StatefulWidget:

@override
void initState() {
  super.initState();
  // 页面渲染完成后只调用一次数据请求
  WidgetsBinding.instance.addPostFrameCallback((_) {
    uiKitTableCtrl.getData(children);
  });
}

@override
Widget build(BuildContext context) {
  return GetBuilder<UiKitTableContoller>(
      init: uiKitTableCtrl,
      builder: (_) {
        return Scaffold(
          body: !uiKitTableCtrl.isSuccess.value
              ? const Center(child: CircularProgressIndicator())
              : ListTreeView(...)
        );
      }
  );
}

如果是StatelessWidget,可以用GetX的控制器生命周期:
在控制器中重写onInit(如果需要页面加载时自动请求数据):

class UiKitTableContoller extends GetxController {
  // ... 原有代码

  @override
  void onInit() {
    super.onInit();
    // 这里传入需要的headRows,或者通过其他方式传递参数
    getData(yourHeadRows);
  }
}

方案2:用Obx替代GetBuilder,利用响应式自动更新

既然已经用了RxBool,直接用Obx可以自动响应变量变化,无需手动调用update(),更可靠:

控制器代码(可简化):

class UiKitTableContoller extends GetxController {
  final TreeViewController treeController = TreeViewController();

  final RxBool isSuccess = false.obs;

  void getData(List<TableRow> headRows) async {
    isSuccess.value = false;
    await Future.delayed(const Duration(seconds: 2));

    // ... 你的数据处理逻辑

    isSuccess.value = true;
    // 不需要调用update(),Obx会自动刷新UI
  }
}

页面代码:

@override
Widget build(BuildContext context) {
  // 同样要把getData移到初始化逻辑,避免重复调用
  return Obx(() {
    return Scaffold(
      body: !uiKitTableCtrl.isSuccess.value
          ? const Center(child: CircularProgressIndicator())
          : ListTreeView(...)
    );
  });
}

方案3:添加加载标记,避免重复请求

如果必须保留现有结构,可以在控制器中添加一个标记,防止重复执行数据请求:

class UiKitTableContoller extends GetxController {
  final TreeViewController _controller = TreeViewController();
  TreeViewController get treeController => _controller;

  final RxBool _isSuccess = false.obs;
  RxBool get isSuccess => _isSuccess;
  bool _hasLoaded = false; // 新增:标记是否已加载过数据

  void getData(List<TableRow> headRows) async {
    if (_hasLoaded) return; // 已加载过直接返回
    _isSuccess.value = false;
    await Future.delayed(const Duration(seconds: 2));

    // ... 数据处理

    _isSuccess.value = true;
    _hasLoaded = true;
    update();
  }
}

内容的提问来源于stack exchange,提问作者Claire

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:53:16