在 FutureBuilder 中使用 GetX 构建列表 - UI 未更新

mla*_*o91 2 flutter flutter-futurebuilder flutter-getx

我正在创建一个待办事项列表(某种)应用程序。我有一个使用 FutureBuilder 的视图,它调用一个函数从 SQLite 数据库中获取文章并显示为卡片。我有一个getx_controller.dart,其中包含可观察的列表:

class Controller extends GetxController {
  // this is the list of items
  var itemsList = <Item>[].obs;
}
Run Code Online (Sandbox Code Playgroud)

我有一个items_controller.dart

  // function to delete an item based on item id
  void deleteItem(id) {
    final databaseHelper = DatabaseHelper();

    // remove item at item.id position
    databaseHelper.deleteItem(tableItems, id);

    print('delete item with id $id');
    this.loadAllItems();
  }
Run Code Online (Sandbox Code Playgroud)

loadAllItems是查询数据库函数

最后,list_builder.dart包含 FutureBuilder

final itemController = Get.put(ItemsController());

@override
  Widget build(BuildContext context) {
    return FutureBuilder<List<Item>>(
        future: itemController.loadAllItems(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return CircularProgressIndicator();
          } else if (snapshot.hasData) {
            print(snapshot.data.toString());
            return Obx(() => ListView.builder(
                itemCount: snapshot.data!.length,
                itemBuilder: (context, index) {
                  return Slidable(
                    actionExtentRatio: 0.25,
                    actionPane: SlidableDrawerActionPane(),
                    child: _itemCard(index, snapshot.data![index]),
                    actions: <Widget>[
                      IconSlideAction(
                          caption: 'Elimina',
                          color: Colors.red,
                          icon: Icons.delete,
                          onTap: () {
                            itemController.deleteItem(snapshot.data![index].id);
                            itemController.loadAllItems();
                          }),
                    ],
                    secondaryActions: <Widget>[
                      IconSlideAction(
                        caption: 'Modifica',
                        color: Colors.blue,
                        icon: Icons.edit,
                        onTap: () {},
                      ),
                    ],
                  );
                }));
          } else {
            return Container(
              child: Text('Loading'),
            );
          }
        });
    // });
  }

Run Code Online (Sandbox Code Playgroud)

我的问题是,当我点击“Elimina”(或者我创建一个新项目,相同的过程)时,ListBuilder 不会刷新屏幕上的列表,尽管重新创建了 itemsList(使用getxController.itemsList = RxList.generate(...))并可观察。

S. *_*GIR 5

使用可观察量时不需要使用FutureBuilder。这是多余的,并使您的代码变得复杂。相反,您应该将等待的 Future(实际数据/项目)分配给您的可观察列表 ( itemList)。你的用户界面应该会自动更新。

所以你的控制器应该看起来像这样:

class Controller extends GetxController {
 // this is the list of items
 var itemsList = <Item>[].obs;

 @override
 onInit()async{
   await loadAllItems();
 }

 loadAllItems()async{
     var databaseResponse= await dbHelper.getAll();

  itemList.assignAll(databaseResponse);
  }

}
Run Code Online (Sandbox Code Playgroud)

您的 UI 构建方法应该只返回观察 (Obx),ListView.builder如下所示,然后您就完成了:

@override
 Widget build(BuildContext context){
   return Obx(() => ListView.builder(
            itemCount: controller.itemList.length,
            itemBuilder: (context, index) {
    var item = comtroller.itemList[index]; // use this item to build your list item
              return Slidable(
Run Code Online (Sandbox Code Playgroud)