复选框列表不会在 flutter getx 中更新
checkbox list does not update in flutter getx
我在 flutter 项目中使用 GetX 进行状态管理。我的问题是,当我单击复选框时,它会更新控制器中的状态,但不会在 UI 中显示结果。一般来说,改变的状态也应该改变 UI 。我不确定是什么问题,但我认为在 getx 中使用可观察变量存在错误。如何解决这个问题呢?如果 post 不清楚,请问我。
这是视图。
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();
}
}
更新答案:
如果您尝试包装一个 Obx
但它不起作用,请改用 GetBuilder<SearchController>
。
GetBuilder<SearchController>(
builder: (_) => controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
: SingleChildScrollView(...))
当您调用 update()
时,无论如何都会使用更新后的值触发重建。我能想到为什么 Obx
不起作用的唯一原因是,也许当涉及列表时,它只响应列表中项目的添加或删除,而不是 属性 中的更改嵌套在里面。
一般来说,您可能会发现在大多数情况下并不真正需要使用基于可观察流的变量。 GetBuilder
可以处理您需要完成的大部分或全部工作,除非您正在做一些基于流的事情(例如绑定到外部 Firebase 集合)。两者都没有错,但是 GetBuilder
是性能最高的选项,因为流的本质是有点贵。
原回答:
我建议您先阅读有关正确使用的文档,然后再声称其他人的代码中存在错误。这适用于您正在使用的任何软件包。
在整个 Readme
和基本计数器应用程序示例中都说明了可观察变量需要放置在 Obx
小部件中,否则没有任何东西会根据更新的状态触发重建一个可观察的 GetX 变量。
你的Container
的child应该是
Obx(() => controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
: SingleChildScrollView(...))
我在 flutter 项目中使用 GetX 进行状态管理。我的问题是,当我单击复选框时,它会更新控制器中的状态,但不会在 UI 中显示结果。一般来说,改变的状态也应该改变 UI 。我不确定是什么问题,但我认为在 getx 中使用可观察变量存在错误。如何解决这个问题呢?如果 post 不清楚,请问我。
这是视图。
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();
}
}
更新答案:
如果您尝试包装一个 Obx
但它不起作用,请改用 GetBuilder<SearchController>
。
GetBuilder<SearchController>(
builder: (_) => controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
: SingleChildScrollView(...))
当您调用 update()
时,无论如何都会使用更新后的值触发重建。我能想到为什么 Obx
不起作用的唯一原因是,也许当涉及列表时,它只响应列表中项目的添加或删除,而不是 属性 中的更改嵌套在里面。
一般来说,您可能会发现在大多数情况下并不真正需要使用基于可观察流的变量。 GetBuilder
可以处理您需要完成的大部分或全部工作,除非您正在做一些基于流的事情(例如绑定到外部 Firebase 集合)。两者都没有错,但是 GetBuilder
是性能最高的选项,因为流的本质是有点贵。
原回答:
我建议您先阅读有关正确使用的文档,然后再声称其他人的代码中存在错误。这适用于您正在使用的任何软件包。
在整个 Readme
和基本计数器应用程序示例中都说明了可观察变量需要放置在 Obx
小部件中,否则没有任何东西会根据更新的状态触发重建一个可观察的 GetX 变量。
你的Container
的child应该是
Obx(() => controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
: SingleChildScrollView(...))