删除最后一项时 AnimatedList 抛出错误

AnimatedList throws error when removing the last item

我正在使用 AnimatedList 可视化在列表中删除和插入项目。当我删除列表底部的项目时,抛出以下错误:RangeError (index): Invalid value: Valid value range is empty: 0,这是当我删除底部的项目但该项目上方仍有项目时抛出的错误或 RangeError (index): Invalid value: Only valid value is 0: 1 删除最后一项时。当我删除列表顶部的项目时,该代码有效,但在删除最后一个项目时失败。是否有一个简单的解决方案,以便我可以毫无问题地删除我的所有项目?

以下是我的代码的简化版本:

class AnimatedListDemo extends StatefulWidget {
  @override
  _AnimatedListDemoState createState() => _AnimatedListDemoState();
}

class _AnimatedListDemoState extends State<AnimatedListDemo> {
  GlobalKey<AnimatedListState> _globalKey = new GlobalKey();
  List<int> items = [];

  Widget _listItem(BuildContext context, int index, animation) {
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(-1, 0),
        end: const Offset(0, 0),
      ).animate(animation),
      child: ListTile(
        title: Text("${items[index]}"),
        trailing: IconButton(
          icon: Icon(Icons.delete),
          onPressed: () {
            setState(() {
              items.removeAt(index);
              _globalKey.currentState.removeItem(index,
                  (context, animation) => _listItem(context, index, animation));
            });
          },
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("AnimatedListDemo"),
          actions: [
            IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                items.add(items.length);
                _globalKey.currentState.insertItem(items.length - 1);
              },
            )
          ],
        ),
        body: AnimatedList(
          key: _globalKey,
          initialItemCount: items.length,
          itemBuilder: (context, index, animation) =>
              _listItem(context, index, animation),
        ),
      ),
    );
  }
}

问题是您试图在 ListTile 标题小部件中显示 items[index],而该元素已被删除。

解决方法可能是:

title: Text(index >= items.length ? '' : items[index].toString()),

所以完整的例子可以变成:

class AnimatedListDemo extends StatefulWidget {
  @override
  _AnimatedListDemoState createState() => _AnimatedListDemoState();
}

class _AnimatedListDemoState extends State<AnimatedListDemo> {
  GlobalKey<AnimatedListState> _globalKey = new GlobalKey();
  List<int> items = [];

  Widget _listItem(BuildContext context, int index, animation) {
    return SlideTransition(
      position: Tween<Offset>(
        begin: const Offset(-1, 0),
        end: const Offset(0, 0),
      ).animate(animation),
      child: ListTile(
        title: Text(index >= items.length ? '' : items[index].toString()),
        trailing: IconButton(
          icon: Icon(Icons.delete),
          onPressed: () {
            setState(() {
              items.removeAt(index);
              _globalKey.currentState.removeItem(index,
                  (context, animation) => _listItem(context, index, animation));
            });
          },
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("AnimatedListDemo"),
          actions: [
            IconButton(
              icon: Icon(Icons.add),
              onPressed: () {
                items.add(items.length);
                _globalKey.currentState.insertItem(items.length - 1);
              },
            )
          ],
        ),
        body: AnimatedList(
          key: _globalKey,
          initialItemCount: items.length,
          itemBuilder: (context, index, animation) =>
              _listItem(context, index, animation),
        ),
      ),
    );
  }
}