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

Flutter使用GetX状态管理时ListView.builder新增数据未实时更新问题求助

问题原因&修复方案

核心问题点

  • 响应式变量items未实际使用:你在Controller中定义了items = <Word>[].obs但所有数据库操作后都没有更新这个变量,obs变量只有值发生变化时才会触发UI更新
  • Obx用法完全错误:Obx是用来包裹需要响应状态变化的Widget组件,不能放在点击事件回调中使用
  • 列表渲染逻辑错误:你用了FutureBuilder每次渲染都重新请求数据库,没有绑定响应式变量,新增数据后自然不会自动刷新

修复步骤

第一步:修改WordController代码

class WordController extends GetxController {
  TextEditingController controllerInput1 = TextEditingController();
  TextEditingController controllerInput2 = TextEditingController();
  var items = <Word>[].obs;
  final translator = GoogleTranslator();

  // 控制器初始化时自动拉取一次数据
  @override
  void onInit() {
    super.onInit();
    getir();
  }

  ekle(Word word) async {
    var val = await WordRepo().add(word);
    showDilog("Kayıt Başarılı");
    // 新增成功后刷新列表数据
    await getir();
    return val;
  }

  updateWord(Word word) async {
    var val = await WordRepo().update(word);
    showDilog("Kayıt Başarılı");
    // 更新成功后刷新列表数据
    await getir();
    return val;
  }

  deleteWord(int? id) async {
    var val = await WordRepo().deleteById(id!);
    // 删除成功后刷新列表数据
    await getir();
    return val;
  }

  getir() async {
    var list = await WordRepo().getAll();
    // 把数据库返回的列表赋值给响应式变量,触发UI更新
    items.assignAll(list);
    print(list);
    return list;
  }

  translateLanguage(String newValue) async {
    if(newValue==null || newValue.length==0){
      return;
    }
    List list=["I","i"];
    if(newValue.length==1 && !list.contains(newValue)){
      return;
    }

    var translate = await translator
        .translate(newValue, from: 'en', to: 'tr');

       controllerInput2.text = translate.toString();
    return translate;
  }
  showDilog(String message) {
    Get.defaultDialog(title: "Bilgi", middleText: message);
  }

    addNote() async {
      var word =
          Word(wordEn: controllerInput1.text, wordTr: controllerInput2.text);
      await ekle(word);
      clear();
  }
clear(){
  controllerInput2.clear();
  controllerInput1.clear();
}
  updateNote() async {
    var word =
        Word(wordEn: controllerInput1.text, wordTr: controllerInput2.text);
    await updateWord(word);
    await getir();
    update();
  }
}

第二步:修改UI层代码

  1. 删除build方法中的controller.getir()调用,已经放在Controller的onInit中自动执行了
  2. 替换historyWordList的实现,删除原有FutureBuilder,改用Obx绑定响应式变量:
Widget get historyWordList {
  // 用Obx包裹列表,只要items变化就自动重绘
  return Obx(() {
    if (controller.items.isEmpty) {
      return const Center(child: Text("暂无数据"));
    }
    return ListView.builder(
      itemCount: controller.items.length,
      itemBuilder: (context, index) {
        final word = controller.items[index];
        return Card(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(5.0)),
          ),
          margin: EdgeInsets.only(left: 8.0, right: 8.0, top: 0.8),
          child: Container(
            color: Colors.white30,
            height: 70.0,
            padding: EdgeInsets.only(left: 8.0, top: 8.0, bottom: 8.0),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: [
                    Text(
                      "İngilizce: ${word.wordEn ?? ""}",
                      style: TextStyle(fontWeight: FontWeight.w600),
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                    ),
                    Text(
                      "Türkçe: ${word.wordTr ?? ""}",
                      style: TextStyle(fontWeight: FontWeight.w400),
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                    ),
                  ],
                ),
                historyIconbutton,
              ],
            ),
          ),
        );
      },
    );
  });
}
  1. 删除favoriIconButton的onPressed中无用的Obx代码和refreshList调用,现在addNote执行后会自动更新items触发列表刷新:
get favoriIconButton {
  return IconButton(
    alignment: Alignment.topRight,
    onPressed: () async {
      bool validatorKontrol = _formKey.currentState!.validate();
      if (validatorKontrol) {
        String val1 = controller.controllerInput1.text;
        String val2 = controller.controllerInput2.text;
        print("$val1 $val2");
        await controller.addNote();
      }
    },
    icon: Icon(
      Icons.forward,
      color: Colors.blueGrey,
      size: 36.0,
    ),
  );
}

补充说明

  • obs是GetX提供的响应式变量包装器,你定义的var items = <Word>[].obs本质是一个RxList,只有对这个RxList做增删改操作(比如add、remove、assignAll)才会触发更新通知
  • Obx是响应式Widget,只要它包裹的Widget中用到了任意obs变量,变量更新时Obx会自动重绘内部的Widget,不需要手动调用setState、update或者刷新页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:54:03