首页 > 解决方案 > 有什么方法可以在 Flutter 中处理应用状态下的 List 吗?

问题描述

我想要几个Lists,我可以Provider提供程序包中提供。我可以添加或删除每个元素。这些列表的元素也是可以更改的对象。我希望我的应用程序对所有这些更改做出反应。

现在我需要为每个列表创建单独的类。它们每个都有一个字段List和方法来访问、删除或添加其元素。这需要大量样板文件,并且很难处理元素领域的变化。

// I would like to use ChangeNotifier here, but then I need to make all fields
// private, write getters and setters for them and assign them manually in
// constructor.
class Model {
  int amount;

  Model(this.amount);
}

class ModelService extends ChangeNotifier {
  final models = <Model>[];

  UnmodifiableListView<Model> get all => UnmodifiableListView(models);

  int get length => models.length;

  remove(Model model) {
    models.remove(model);
    notifyListeners();
  }

  add(Model model) {
    models.add(model);
    notifyListeners();
  }

  Model elementAt(int index) => models.elementAt(index);

  elementChanged() => notifyListeners();
}

class ExampleWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) => Column(
    children: [
      RaisedButton(
        child: Text('Add model'),
        onPressed: () => Provider.of<ModelService>(context).add(Model(0)),
      ),
      Expanded(
        child: Consumer<ModelService>(
          builder: (context, service, child) {
            return ListView.builder(
              itemBuilder: (context, index) {
                if (index >= service.length) {
                  return null;
                }

                final model = service.elementAt(index);

                return ListTile(
                  leading: IconButton(
                    icon: Icon(Icons.add),
                    onPressed: () {
                      model.amount++;
                      service.elementChanged();
                    },
                  ),
                  title: Text(model.amount.toString()),
                  trailing: IconButton(
                    icon: Icon(Icons.delete),
                    onPressed: () => service.remove(model),
                  ),
                );
              },
            );
          },
        ),
      ),
    ],
  );
}

有没有更简单或更惯用的方法来处理这种情况?

标签: listflutterstate-management

解决方案


您可以使用泛型使您的对象可重用:

class ModelService<Model> extends ChangeNotifier {
  final models = <Model>[];

  UnmodifiableListView<Model> get all => UnmodifiableListView(models);

  int get length => models.length;

  remove(Model model) {
    models.remove(model);
    notifyListeners();
  }

  add(Model model) {
    models.add(model);
    notifyListeners();
  }

  Model elementAt(int index) => models.elementAt(index);

  elementChanged() => notifyListeners();
}

我经常做的事情是从该类继承并为其添加额外的逻辑:排序、获取、过滤、保存等。例如:

class TodoService extends ModelService<Todo> {
  add(Todo model) {
    super.add(model);
    // save the list on disk
  }

  void setSearchText(String searchText) {
    // apply search text on the models list
  }
}

这样,您的小部件可以变得更加简单。


推荐阅读