Estoy usando GetX para la gestión estatal en el proyecto flutter. Mi problema es que cuando hago clic en la casilla de verificación, actualiza el estado en el controlador pero no muestra el resultado en la interfaz de usuario. En general, el estado modificado también debería cambiar la interfaz de usuario. No estoy seguro de cuál es el problema, pero creo que hay un error al usar la variable observable en getx. ¿Cómo resolver este problema? Si la publicación no está clara, por favor pregúnteme.
Esta es la vista.
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 ], ), ); } }
Esto es 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(); } }
Respuesta actualizada:
Si intentó envolver un Obx
y no funcionó, use GetBuilder<SearchController>
en su lugar.
GetBuilder<SearchController>( builder: (_) => controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100) : SingleChildScrollView(...))
Cuando llame a update()
, se activará una reconstrucción sin importar qué, con los valores actualizados. La única razón por la que se me ocurre por qué Obx
no funcionó es que, quizás, cuando se trata de listas, solo responde a la adición o eliminación de un elemento de la lista y no a un cambio en una propiedad anidada en su interior.
En general, probablemente encontrará que, en la mayoría de los casos, no es realmente necesario usar una variable basada en flujo observable. GetBuilder
puede manejar la mayoría o la totalidad de lo que necesita hacer, a menos que esté haciendo algo basado en secuencias (vinculándose a una colección externa de Firebase, por ejemplo). Tampoco tiene nada de malo, pero GetBuilder
es la opción de mayor rendimiento ya que las transmisiones, por su naturaleza, son un poco más caras.
Respuesta original:
Le sugiero que lea los documentos sobre el uso adecuado antes de afirmar que hay un error en el código de otra persona. Eso se aplica a cualquier paquete que esté utilizando.
Se indica en todo el Readme
y en el ejemplo básico de la aplicación de contador que las variables observables deben colocarse en un widget Obx
; de lo contrario, no hay nada que desencadene una reconstrucción basada en el estado actualizado de una variable GetX observable.
El hijo de su Container
debe ser
Obx(() => controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100) : SingleChildScrollView(...))