首页 > 解决方案 > 复选框列表不会在颤振 getx 中更新

问题描述

我在颤振项目中使用 GetX 进行状态管理。我的问题是当我单击复选框时,它会更新控制器中的状态,但不会在 UI 中显示结果。一般来说,改变的状态也应该改变 UI。我不确定是什么问题,但我认为在 getx 中使用 observable 变量存在错误。如何解决这个问题呢?如果帖子不清楚,请问我。

这是视图。

class FilterBottomSheetWidget extends GetView<SearchController> {
@override
Widget build(BuildContext context) {
  return Container(
  height: Get.height - 90,
  child: Stack(
    children: <Widget>[
      Padding(
        padding: const EdgeInsets.only(top: 80),
        child: Container(
          padding: EdgeInsets.only(top: 20, bottom: 15, left: 4, right: 4),
          child: controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
            : SingleChildScrollView(
              scrollDirection: Axis.vertical,
              child: ExpansionTile(
                      title: Text("Contract Status".tr, style: Get.textTheme.bodyText2),
                      children: List.generate(controller.expiringContractStatus.length, (index) {
                        var _expiringContractStatus = controller.expiringContractStatus.elementAt(index);
                        return CheckboxListTile(
                          controlAffinity: ListTileControlAffinity.trailing,
                          value: _expiringContractStatus["isCheck"], // ************
                          onChanged: (value) {
                            controller.itemChange(value, index); // ************
                            controller.update();
                          },
                          title: Text(
                            _expiringContractStatus["title"],
                            style: Get.textTheme.bodyText1,
                            overflow: TextOverflow.fade,
                            softWrap: false,
                            maxLines: 1,
                          ),
                        );
                      }),
                      initiallyExpanded: true,
                    );
                  }                   
            )
        ),
      ),
     // more widgets
    ],
  ),
);
 }
 }

这是搜索控制器。

class SearchController extends GetxController {
final expiringContractStatus = <Map>[
  {
    "title": "aaa",
    "isCheck": false
  },
  {
    "title": "bbb",
    "isCheck": false
  },
  {
    "title": "ccc",
    "isCheck": false
  }        
].obs;

@override
void onInit() async {
  await refreshSearch();
  super.onInit();
}

void itemChange (bool value, int index) {
  expiringContractStatus[index]["isCheck"] = value; // *************
  update();
}
}

标签: javascriptflutterdartflutter-layoutflutter-getx

解决方案


更新答案:

如果您尝试包装 anObx但它不起作用,请GetBuilder<SearchController>改用。

GetBuilder<SearchController>(
    builder: (_) =>  controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
            : SingleChildScrollView(...))

当您调用update()它时,无论如何都会使用更新的值触发重建。我能想到为什么Obx不起作用的唯一原因是,当涉及到列表时,可能只响应列表中项目的添加或删除,而不是嵌套在其中的属性的更改。

通常,您可能会发现在大多数情况下,实际上并不需要使用基于可观察流的变量。GetBuilder可以处理您需要完成的大部分或全部工作,除非您正在做一些基于流的事情(例如绑定到外部 Firebase 集合)。两者都没有错,但GetBuilder它是性能最高的选择,因为流本质上要贵一些。

原答案:

我建议您在声称其他人的代码中存在错误之前阅读有关正确使用的文档。这适用于您正在使用的任何软件包。

Readme基本的计数器应用程序示例中到处都说明了可观察变量需要放置在Obx小部件中,否则不会根据可观察 GetX 变量的更新状​​态触发重建。

你的孩子Container应该是

Obx(() => controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
            : SingleChildScrollView(...))

推荐阅读