【问题标题】:How to clear all items from an AnimatedList in Flutter如何在 Flutter 中清除 AnimatedList 中的所有项目
【发布时间】:2019-06-19 22:47:05
【问题描述】:

我试图在 AnimatedList 上预先生成所有更新操作,就像我为 Android 中的 RecyclerView 适配器所做的那样。但是当我要清除所有数据时,我不知道该怎么做。

如果我这样做

setState(() {
  _data.clear();
});

然后后台数据被清除,但是 GlobalKey 的当前状态仍然不知道变化,并且上面没有clear() 方法。

补充代码

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(title: Text('Update AnimatedList data')),
        body: BodyWidget(),
      ),
    );
  }
}

class BodyWidget extends StatefulWidget {
  @override
  BodyWidgetState createState() {
    return new BodyWidgetState();
  }
}

class BodyWidgetState extends State<BodyWidget> {

  // the GlobalKey is needed to animate the list
  final GlobalKey<AnimatedListState> _listKey = GlobalKey();

  // backing data
  List<String> _data = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        SizedBox(
          height: 400,
          child: AnimatedList(
            key: _listKey,
            initialItemCount: _data.length,
            itemBuilder: (context, index, animation) {
              return _buildItem(_data[index], animation);
            },
          ),
        ),
        RaisedButton(
          child: Text(
            'Clear all items',
            style: TextStyle(fontSize: 20),
          ),
          onPressed: () {
            _clearAllItems();
          },
        )
      ],
    );
  }

  Widget _buildItem(String item, Animation animation) {
    return SizeTransition(
      sizeFactor: animation,
      child: Card(
        child: ListTile(
          title: Text(
            item,
            style: TextStyle(fontSize: 20),
          ),
        ),
      ),
    );
  }

  void _clearAllItems() {
    _data.clear();
    // no such method
    _listKey.currentState.clear();
  }

}

【问题讨论】:

    标签: dart flutter flutter-animatedlist


    【解决方案1】:

    您必须手动删除 _listKey.currentState 中的项目

    示例代码:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: Scaffold(
            appBar: AppBar(title: Text('Update AnimatedList data')),
            body: BodyWidget(),
          ),
        );
      }
    }
    
    class BodyWidget extends StatefulWidget {
      @override
      BodyWidgetState createState() {
        return new BodyWidgetState();
      }
    }
    
    class BodyWidgetState extends State<BodyWidget> {
      // the GlobalKey is needed to animate the list
      final GlobalKey<AnimatedListState> _listKey = GlobalKey();
    
      // backing data
      List<String> _data = ['Horse', 'Cow', 'Camel', 'Sheep', 'Goat'];
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: <Widget>[
            SizedBox(
              height: 400,
              child: AnimatedList(
                key: _listKey,
                initialItemCount: _data.length,
                itemBuilder: (context, index, animation) {
                  return _buildItem(_data[index], animation);
                },
              ),
            ),
            RaisedButton(
              child: Text(
                'Clear all items',
                style: TextStyle(fontSize: 20),
              ),
              onPressed: () {
                _clearAllItems();
              },
            )
          ],
        );
      }
    
      Widget _buildItem(String item, Animation animation) {
        return SizeTransition(
          sizeFactor: animation,
          child: Card(
            child: ListTile(
              title: Text(
                item,
                style: TextStyle(fontSize: 20),
              ),
            ),
          ),
        );
      }
    
      void _clearAllItems() {
        for (var i = 0; i <= _data.length - 1; i++) {
          _listKey.currentState.removeItem(0,
              (BuildContext context, Animation<double> animation) {
            return Container();
          });
        }
        _data.clear();
      }
    }
    

    【讨论】:

    • 我害怕那个。感谢您的确认。
    • 今天还有什么比这更好的吗?
    【解决方案2】:

    每次您将新密钥传递给 AnimatedList 小部件时,它都会重新创建其状态并在下一次使用全新的项目列表进行重建:

    var _listKey = GlobalKey<AnimatedListState>();
    
    void _clearAllItems() {
      _data.clear();
      setState(() => _listKey = GlobalKey());
    }
    

    【讨论】:

    • 接受的解决方案可能“更正确”,因为它会为更改设置动画;但是,这对我的用例很有效(在用户输入搜索查询后更新列表)。我还需要一个解决方案来在应用程序的其他地方触发事件后重新加载列表,而无需迭代新旧列表并记录差异。对于这些情况,此解决方案效果很好。
    • 清洁和良好的解决方案。应该让人们深入了解按键的工作原理。
    猜你喜欢
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 2019-10-24
    • 2011-09-24
    • 2019-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多