当使用Flutter GetX时,数据发生更改时如何刷新ListView.Builder中的UI?

14

我正在重构我的应用程序,使用GetX状态管理来减少冗长的代码。 我创建了控制器和API提供程序(下面是代码)。 但当我想要刷新数据时(也可以手动刷新),它不会改变。

home_page.dart

class HomeUI extends GetView<HomeController> {
...
GetX<HomeController>(
                          initState: (state) => Get.find<HomeController>().getAll(),
                          builder: (_) {
                                    return _.goalList.length < 1 ||
                                            _.goalList == null
                                        ? Center(
                                            child: Column(
                                            mainAxisAlignment:
                                                MainAxisAlignment.center,
                                            children: [
                                              CircularProgressIndicator(),
                                              Text('0 goals found, please wait',
                                                  style: Theme.of(context)
                                                      .textTheme
                                                      .headline6
                                                      .copyWith(
                                                          color: kTextColor))
                                            ],
                                          ))
                                        : ListView.builder(
                                            itemBuilder: (context, index) {
                                            GoalModel goalModel =
                                                GoalModel.fromMap(
                                                    _.goalList[index]);

                                            return ListTile(
                                              title: Text(goalModel.text),
                                              subtitle:
                                                  Text(goalModel.updated_at),
                                            );
                                          });
}                                                                         

home_controller.dart

class HomeUI extends GetView<HomeController> {
...


class HomeController extends GetxController {
  final MyRepository repository = MyRepository();

  final _goalsList = RxList();
  get goalList => this._goalsList.value;
  set goalList(value) => this._goalsList.value = value;

  getAll() {
    repository.getAll().then((data) {
      this.goalList = data;
      update();
    });
  }

  delete(id) {
    repository.delete(id).then((message) {
      this.goalList;
      return message;
    });
  }

  add(goal) {
    repository.add(goal).then((data) {
      this.goalList = data;
    });
  }

  edit(editedItem, text, achievementDate) {
    repository.edit(editedItem, text, achievementDate).then((data) {
      this.goalList = data;
    });
  }
}                                                                       

goals_repository.dart

class MyRepository {
  final MyApiClient apiClient = MyApiClient();

  getAll() {
    return apiClient.getAll();
  }

  delete(id) {
    return apiClient.deleteGoal(id);
  }

  edit(editedItem, text, achievementDate) {
    return apiClient.updateGoal(editedItem, text, achievementDate);
  }

  add(goal) {
    return apiClient.postGoal(goal);
  }
}                                                                    

api.dart(getAll() 方法)

  getAll() async {
    try {
      var _token = await _sharedPrefsHelper.getTokenValue();

      var response = await httpClient.get(baseUrl, headers: {
        'Authorization': 'Bearer $_token',
      });
      if (response.statusCode == 200) {
        print('json decode response is: ${json.decode(response.body)}');

        return json.decode(response.body);
      } else
        print('erro -get');
    } catch (error) {
      print(error);
    }
  }

我按照这篇文章的步骤进行了实现:getx_pattern


你可以分享整个项目(请提供 github 链接)以便检查吗? - Ουιλιαμ Αρκευα
1
@ΟυιλιαμΑρκευα 我也有同样的问题。我的测试项目在这里:https://github.com/mjablecnik/flutter_getx_example - mjablecnik
1
请看下面我发布的答案,请检查一下。 - Ουιλιαμ Αρκευα
1
非常感谢,我已经通过这个提交修复了它:https://github.com/mjablecnik/flutter_getx_example/commit/e92dc4a80dcbc8a7b17520082deac4a082d7de40 - mjablecnik
1
你解决了吗?我也遇到了这个问题。 - chichi
你好,你在任何重要的工作中使用过这个模式吗?这个模式有用吗? - Anoop Thiruonam
4个回答

18
手动更新列表后,请执行以下操作:
this._goalsList.refresh()

之后您的用户界面将会被更新


8

只需使用ObxGetxListView.builder列表包装起来即可。对于不在列表中的小部件,您可以单独使用obx或getx进行包装。

例如:

Obx(() => ListView.builder(
            physics: const NeverScrollableScrollPhysics(),
            itemCount: item.length,
            shrinkWrap: true,
            itemBuilder: (BuildContext context, int index) {
              return Card()...
            },
          ),
        ),

3

如上所述,Obs Getx变量仅在Obx或Getx内部被观察到。您需要将它们包装起来。只需小心,不要在没有观察到变量的情况下使用Obx / Getx,因为这会生成错误。


2
这篇回答是针对@mjablecnik的评论的:
class Other extends StatelessWidget {
  final Counter c = Get.find();
  final _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
  final Random _rnd = Random();
  /* ---------------------------------------------------------------------------- */
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Obx(() => ListView.builder(
          scrollDirection: Axis.vertical,
          padding: EdgeInsets.all(10),
          itemCount: c.testList.length,
          itemBuilder: (context, index) => Card(
            color: Colors.amber[600],
            child: Padding(
              padding: const EdgeInsets.all(10),
              child: Center(
                child: Text('${c.testList[index]}'),
              ),
            ),
          ),
        )),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () => c.addToList(getRandomString(15)),
      ),
    );
  }
  /* ---------------------------------------------------------------------------- */
  // source: https://dev59.com/IVIG5IYBdhLWcg3w_nNR
  String getRandomString(int length) => String.fromCharCodes(Iterable.generate(
      length, (_) => _chars.codeUnitAt(_rnd.nextInt(_chars.length))
    )
  );
}

更新1:

我做的另一个小改变是针对控制器的:

class Counter extends GetxController {
  var count = 0.obs;
  var testList = <String>['test1', 'test2'].obs;
  /* ---------------------------------------------------------------------------- */
  void incremenent() => count++;
  /* ---------------------------------------------------------------------------- */
  void addToList(String item) {
    print('adding: $item');
    testList.add(item);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接