在 Flutter 中的网格中动画项目删除

Posted

技术标签:

【中文标题】在 Flutter 中的网格中动画项目删除【英文标题】:Animating item removal in a grid in Flutter 【发布时间】:2020-07-19 22:34:57 【问题描述】:

我有一个使用Wrap 小部件的方框网格(我没有使用GridView,因为这需要您提前说明每行需要多少项目)。

我想在单击项目时将其删除,并让所有其他项目以动画方式移动到它们的新位置,如下所示:https://vestride.github.io/Shuffle/adding-removing(单击框以了解我的意思)。

这是我到目前为止没有任何动画的代码:

class Boxes extends StatefulWidget 
  @override
  _BoxesState createState() => _BoxesState();


class _BoxesState extends State<Boxes> 
  var items = [
    'id': '25', 'name': 'A',,
    'id': '19', 'name': 'B',,
    'id': '35', 'name': 'C',,
    'id': '20', 'name': 'D',,
    'id': '958', 'name': 'E',,
    'id': '1278', 'name': 'F',,
    'id': '500', 'name': 'G',,
  ];

  Widget build(BuildContext context) 
    return Container(
      width: double.infinity,
      height: double.infinity,
      child: Wrap(
        alignment: WrapAlignment.center,
        children: [
          for (final item in items)
            Box(
              key: Key(item['id']),
              name: item['name'],
              onDelete: () 
                setState(() 
                  items.remove(item);
                );
              ,
            )
        ],
      ),
    );
  


class Box extends StatelessWidget 
  String name;
  Function onDelete;

  Box(this.name, this.onDelete, Key key):
    super(key: key);

  Widget build(BuildContext context) 
    return GestureDetector(
      onTap: onDelete,
      child: Container(
        color: Colors.lightBlue,
        width: 90,
        height: 90,
        margin: EdgeInsets.all(8),
        child: Center(
          child: Text(name),
        )
      ),
    );
  

我能找到的最接近的内置小部件是AnimatedList,但这不适用于网格。 我还尝试将已删除框的宽度设置为 0,这不起作用,因为其他框只是跳到位置而不是动画到新位置。

我该怎么做呢?

感谢您的帮助。

【问题讨论】:

嘿,你找到解决办法了吗? 【参考方案1】:

你可以试试AnimatedContainer

当点击事件发生时,我基本上将宽度从 100 更改为 0。

我也稍微改变了列表项。

AnimatedContainer 检测到属性宽度发生变化并触发动画。

请尝试这样的事情(与您的参考不同)

我评论了items.remove(item),你需要找到一种方法在动画完成后真正删除该项目(可能有一个计时器或未来)。

  List<Map<String,dynamic>> items = [
     'id':'11','name':'A','width':100,
     'id':'12','name':'B','width':100,
     'id':'13','name':'C','width':100,
     'id':'14','name':'D','width':100,
     'id':'15','name':'E','width':100,
     'id':'16','name':'F','width':100,
     'id':'17','name':'G','width':100,
  ];

  Widget build(BuildContext context) 
    return Scaffold(body: Container(
      width: double.infinity,
      height: double.infinity,
      child: Wrap(
        alignment: WrapAlignment.center,
        children: [
          for (final item in items)
            AnimatedContainer(
              width: double.parse(item['width'].toString()),
              duration: Duration(milliseconds: 600),
              curve: Curves.easeInBack,
              child: Box(
                key: Key(item['id']),
                name: item['name'],
                onDelete: () 
                  setState(() 
                    //items.remove(item);
                    item['name'] = "";
                    item['width'] = 0;
                  );
                ,
              ),
            )
        ],
      ),
    ));
  

Flutter 视频 --> https://www.youtube.com/watch?v=yI-8QHpGIP4

【讨论】:

谢谢,但我已经尝试了问题中提到的类似解决方案。这样做的问题是,当盒子改变位置时,它不是动画的。它只是跳转到新位置。 它是动画的。盒子不会跳跃和消失,它们会在过渡中消失。 但下一行中的框不会动画到新位置。这就是我想要的:vestride.github.io/Shuffle/adding-removing

以上是关于在 Flutter 中的网格中动画项目删除的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 动画列表:有条件地添加 ListView 项

Flutter:在 ListView 中动画项目删除

Flutter PageView,我可以动画从列表中删除项目吗?

在 Flutter 中实现文字动画

如何在flutter中重建所有网格项?

在 Flutter 中,您如何制作动画以将容器从 0 高度扩展到其内容的高度?