我看到很多人遇到非常相似的问题,但是我尝试的都没有。

CONTEXT

我列出了最喜欢的想法。每当我单击ideaItem内的按钮时,它都应该从列表中删除。

问题

当我删除任何ideaItem时,总是会删除屏幕上的最后一个,而不是我单击的那个。我的FavoriteIdeasListView似乎可以正确更新项目计数,这意味着附加的List可以工作,但是UI不会重绘ideaItems。

我尝试过的内容

  • 刚开始时,我直接在ideaItem上具有删除功能,我读到我应该做一个VoidCallback并处理从List本身的删除,因此它会注意到更改。
  • 无效
  • 我也尝试过使用Stream Builder,因此流将通知ListView刷新。也没有用
  • 我一直尝试调用SetState,并且不会重新加载,它只会在initialState的开始处构建列表。
  • 
        class FavoritesList extends StatefulWidget {
          FavoritesList({Key key}) : super(key: key);
    
          @override
          _FavoritesListState createState() => _FavoritesListState();
        }
    
        class _FavoritesListState extends State<FavoritesList> {
    
          List<Idea> _favorites = [];
    
          @override
          void initState() {
            super.initState();
            favoritesInitialState();
          }
    
          Future <void> favoritesInitialState() async {
            List<Idea> ideas = await IdeasDB.db.ideas();
            setState(() {
              _favorites = ideas;
            });
          }
    
          @override
          Widget build(BuildContext context) {
            return Scaffold(
                appBar: AppBar(
                    title: Text('Favorites')),
                body: Center(
                  child: ListView.builder(
                    itemCount: _favorites.length,
                    itemBuilder: (context, index) {
                      final idea = _favorites[index];
                      return IdeaItem(
                        idea: idea,
                        onFavoriteToggle: () => deleteFromFavorites(idea),
                      );
                    },
                  ),
                )
            );
          }
    
          void deleteFromFavorites(Idea idea) async {
            await IdeasDB.db.deleteIdea(idea.url);
            List<Idea> newIdeas = await IdeasDB.db.ideas();
            setState(() {
              this._favorites = newIdeas;
            });
          }
        }
    

    最佳答案

    对于这种情况,我只能看到两个可能的选择。

    第一个很明显,您的IdeasDB.db.deleteIdea(idea.url);不会从数据库中删除正确的想法;

    第二个不那么明显,这是因为您的元素树无法识别您要删除的小部件。它仅在有状态Widget时发生,因为IdeaItem可能是这样。

    然后的解决方案是将key属性用于IdeaItem小部件
    像这样:

    ListView.builder(
      itemCount: _favorites.length,
      itemBuilder: (context, index) {
        final idea = _favorites[index];
        return IdeaItem(
          key: ValueKey(idea.url) // or UniqueKey()
          idea: idea,
          onFavoriteToggle: () => deleteFromFavorites(idea),
        );
      },
    ),
    

    并在IdeaItem小部件中,您必须将该密钥传递给父Stateful widget,如以下示例所示:
    class IdeaItem extends StatefulWidget {
      final Idea idea;
      Function onFavoriteToggle;
    
      IdeaItem({Key key, this.idea, this.onFavoriteToggle}) : super(key: key);
    
      @override
      _IdeaItemState createState() => _IdeaItemState();
    }
    

    08-18 07:58