Как обновить ListView после добавления нового объекта в список?

Я пытался использовать GetBuilder для обновления состояния, но не работает. Новый объект отображается в списке, если я выполняю горячую перезагрузку, но страница не заполняется новыми элементами. Должен ли я перезагружать страницу или использовать реактивный Observable? Также, когда я пытаюсь сделать список еды наблюдаемым с помощью foodList.obs, я получаю сообщение об ошибке, потому что я не могу сделать наблюдаемыми объекты типа еды. Очень странный.

class FoodsController extends GetxController {
  List<Food> foodList = [];
  int nrOfFoods;

  onInit() {
    foodList.add(Food(name: 'banana', type: 'fruits'));
    foodList.add(Food(name: 'apples', type: 'fruits'));
    foodList.add(Food(name: 'melon', type: 'fruits'));
    super.onInit();
  }

  @override
  void onReady() {
    nrOfFoods.obs;
    super.onReady();
  }
  void addItem(Food item) {
    foodList.add(item);
    nrOfFoods = foodList.length;
    update();
  }
}

class HomePage extends StatelessWidget {
  FoodsController foodsController = Get.put(FoodsController());
  @override
  Widget build(BuildContext context) {
    print(foodsController.foodList);
    return Scaffold(
      appBar: AppBar(
        title: Text('App Bar'),
      ),
      body: Column(
        children: [
          Expanded(
            child: GetBuilder<FoodsController>(
              init: FoodsController(),
              builder: (_) => ListView.builder(
                itemCount: foodsController.foodList.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(
                      title: Text(foodsController.foodList[index].name));
                },
              ),
            ),
          ),
          FloatingActionButton(
            child: Text("test"),
            onPressed: () => {
              foodsController.foodList.add(Food(name: "chicken", type: "meat")),
              Get.to(SecondPage())
            },
          ),
        ],
      ),
    );
  }
}

Спасибо

1 ответ

Я нашел решение. Я переместил контроллер на вторую страницу, и теперь все в порядке, хотя я думаю, что мне следует использовать Obx вместо GetBuilder, чтобы сделать это реактивным.

class Food {
  Food({this.name, this.type});
  String name, type;

  @override
  String toString() => '${this.name} is a ${this.type}';
}

class FoodsController extends GetxController {
  final List<Food> foodList = [];
  int nrOfFoods = 0;

  onInit() {
    foodList.add(Food(name: 'banana', type: 'fruits'));
    foodList.add(Food(name: 'apples', type: 'fruits'));
    foodList.add(Food(name: 'melon', type: 'fruits'));
    super.onInit();
  }

  void addItem(Food item) {
    foodList.add(item);
    nrOfFoods = foodList.length;
    update();
  }
}

class HomePage extends StatelessWidget {
  final FoodsController foodsController = Get.put(FoodsController());

  @override
  Widget build(BuildContext context) {
    print(foodsController.foodList);
    return Scaffold(
      appBar: AppBar(
        title: Text('App Bar'),
      ),
      body: Column(
        children: [
          FloatingActionButton(
            child: Text("test"),
            onPressed: () {
              foodsController.foodList.add(Food(name: "chicken", type: "meat"));
              Get.to(SecondPage());
            },
          ),
        ],
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  final FoodsController ctrl = Get.find();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('App Bar'),
      ),
      body: Column(
        children: [
          Expanded(
            child: GetBuilder<FoodsController>(
              builder: (_) => ListView.builder(
                itemCount: ctrl.foodList.length,
                itemBuilder: (BuildContext context, int index) {
                  return ListTile(title: Text(ctrl.foodList[index].name));
                },
              ),
            ),
          ),
          FloatingActionButton(
            child: Text("test"),
            onPressed: () {
              ctrl.foodList.add(Food(name: "chicken", type: "meat"));
              Get.to(SecondPage());
            },
          ),
        ],
      ),
    );
  }
}

Спасибо

Другие вопросы по тегам