复选框列表在flutter getx中未更新



我在flutter项目中使用GetX进行状态管理。我的问题是,当我点击复选框,它更新状态在控制器,但不显示在UI的结果。一般来说,状态的改变也应该改变UI。我不确定是什么问题,但我认为有一个bug在使用getx的可观察变量。如何解决这个问题?如果帖子不清楚,请问我。

这是视图。

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

This is SearchController.

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

更新答案:

如果你尝试包装一个Obx,它不工作,使用GetBuilder<SearchController>代替。

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

当你调用update(),它将触发重建无论什么,更新的值。我能想到为什么Obx没有工作的唯一原因是,也许当它涉及到列表时,只响应列表中添加或删除一个项目,而不是在其中嵌套的属性更改。

一般来说,你可能会发现在大多数情况下,使用基于可观察流的变量是不需要的。GetBuilder可以处理大部分或所有你需要做的事情,除非你正在做一些基于流的事情(绑定到一个外部Firebase集合,例如)。这两种都没有错,但是GetBuilder是性能最好的选择,因为流从本质上来说有点贵。

原始回答:

我建议你在声称别人的代码中有bug之前,先阅读有关正确用法的文档。这适用于您正在使用的任何软件包。

Readme和基本计数器应用程序示例中都指出,可观察变量需要放置在Obx小部件中,否则不会触发基于可观察GetX变量更新状态的重建。

Container的子节点应该是

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

最新更新