flutter - 更改项目状态后如何更新列表? ( flutter 和提供者)

标签 flutter dart state provider state-management

大家好,感谢您看我的问题,
我有这个问题:我有一个项目列表,每个项目都有一个最喜欢的状态,我有一个页面显示最喜欢的项目。当我切换收藏状态时,我希望页面更新和删除不喜欢的项目。
尝试使用 ChangeNotifierProxyProvider 也没有成功,状态正在改变,但 notifyListeners 没有更新主列表。
我知道在应用程序中间使用 enpty setState 只是为了触发刷新的技巧,但我知道有一个更简洁的方法涉及我不知道的 Provider。
再次感谢!
这是代码(我让它尽可能短)

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Collection(),
      builder: (context, child) => MaterialApp(
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _list = Provider.of<Collection>(context).favItems;

    return Scaffold(
      appBar: AppBar(
        title: Text("Test"),
      ),
      body: Container(
        child: ListView.builder(
          itemCount: _list.length,
          itemBuilder: (_, index) => ChangeNotifierProvider.value(
            value: _list[index],
            child: CardWidget(),
          ),
        ),
      ),
    );
  }
}

class CardWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _item = Provider.of<Items>(context);

    return Card(
      child: Row(
        children: <Widget>[
          Text(_item.name),
          IconButton(
              icon:
                  _item.favourite ? Icon(Icons.star) : Icon(Icons.star_border),
              onPressed: () {
                _item.toggleFavourite();
              })
        ],
      ),
    );
  }
}

class Collection with ChangeNotifier {
  List<Items> _items = [
    Items(name: "a", favourite: true),
    Items(name: "b", favourite: true),
    Items(name: "c", favourite: true),
  ];

  List<Items> get favItems =>
      [..._items].where((element) => element.favourite == true).toList();
}

class Items with ChangeNotifier {
  String name;
  bool favourite;

  Items({this.name, this.favourite});

  toggleFavourite() {
    favourite = !favourite;
    notifyListeners();
  }
}

最佳答案

老实说,Provider 的工作方式是将数据沿小部件树向下传播,从父级到子级,但您希望子级( Item )通知父级更改( Collection ),这将使父级和 child 相互依赖(并且稍后会导致一些意大利面条代码)。如果对收藏夹的每次更改都会更新列表,那么最好将整个逻辑保留在 Collection 中。并保留 Item作为 simpel 模型的类

class Collection with ChangeNotifier {
  List<Items> _items = [
    Items(name: "a", favourite: true),
    Items(name: "b", favourite: true),
    Items(name: "c", favourite: true),
  ];

  List<Items> get favItems =>
      [..._items].where((element) => element.favourite == true).toList();

  toggleFavourite(Item item) {
    int index = _items.indexWhere((element) => element.name == item.name);
    _items[index].favourite = !_items[index].favourite;
    notifyListeners();
  }
}

class Items { //simple Model class
  String name;
  bool favourite;

  Items({this.name, this.favourite});
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final _list = context.select((Collection list) => list.favItems); 
    //to update only if list is different

    return Scaffold(
      appBar: AppBar(
        title: Text("Test"),
      ),
      body: Container(
        child: ListView.builder(
          itemCount: _list.length,
          itemBuilder: (_, index) => CardWidget(_list[index])
        ),
      ),
    );
  }
}

class CardWidget extends StatelessWidget {
  final Item _item;

  CardWidget(this._item);

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Row(
        children: <Widget>[
          Text(_item.name),
          IconButton(
              icon:
                  _item.favourite ? Icon(Icons.star) : Icon(Icons.star_border),
              onPressed: () {
                Provider.of<Collection>(context, listen: false).toggleFavourite(_item);
              })
        ],
      ),
    );
  }
}

关于flutter - 更改项目状态后如何更新列表? ( flutter 和提供者),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62865729/

相关文章:

spring-boot - 如何将 JWT 从 spring boot 发送到 Flutter?

ios - 为什么 Flutter 编译器告诉我我的应用程序不存在?

flutter - just_audio - 完成后的音频播放器,从头开始

flutter - 如何突出显示我在字符串中搜索的确切单词,而不只是字符串的开头?

angularjs - 将 UI-Router 状态参数从父级一致传递到子级

android-studio - Dart/Flutter防止格式化程序将方法调用压缩到一行

flutter - 使用参数调用的方法与不使用参数的方法之间的区别

flutter - Flutter:将列表另存为收藏

Flutter:Widget State:这段代码安全吗?

python - 有没有办法使 tkinter Frame 变灰(禁用)?