美文网首页
Flutter 组件之 AnimatedList 动态列表

Flutter 组件之 AnimatedList 动态列表

作者: Abner_XuanYuan | 来源:发表于2023-10-15 11:31 被阅读0次

    1、作用

    AnimatedList 和 ListView 的功能大体相似,不同的是, AnimatedList 可以在列表中插入或删除节点时执行一个动画,在需要添加或删除列表项的场景中会提高用户体验。
    AnimatedList 是一个 StatefulWidget,它对应的 State 类型为 AnimatedListState,添加和删除元素的方法位于 AnimatedListState 中。

    2、常用属性

    AnimatedList AnimatedList({
      Key? key,    //组件标识符
      required Widget Function(BuildContext, int, Animation<double>) itemBuilder,    //生成每个列表的回调函数
      int initialItemCount = 0,    //创建时的 item 个数
      Axis scrollDirection = Axis.vertical,    //滚动方向,默认垂直
      bool reverse = false,     //是否反向循环,默认 false
      ScrollController? controller,    //Scroll 控制器
      bool? primary,    // 是否与父级滚动关联
      ScrollPhysics? physics,    // 滚动如何响应用户操作
      bool shrinkWrap = false,    //AnimatedList 是否包裹所有子 item,默认 false
      EdgeInsetsGeometry? padding,    // 内边距
      Clip clipBehavior = Clip.hardEdge,    //组件内容边缘的裁剪方式
    })
    

    3、AnimatedList 增加列表

    1、FadeTransition
    class HomePage extends StatefulWidget {
      const HomePage({super.key});
    
      @override
      State<HomePage> createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      final globalKey = GlobalKey<AnimatedListState>();
      List<String> list = ["第一条数据", "第二条数据"];
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              list.add("这是一个数据");
              globalKey.currentState!.insertItem(list.length - 1);
            },
            child: const Icon(Icons.add),
          ),
          appBar: AppBar(
            title: const Text("AppBar组件"),
          ),
          body: AnimatedList(
              key: globalKey,
              initialItemCount: list.length,
              itemBuilder: (context, index, animation) {
                return FadeTransition(
                  opacity: animation,
                  child: ListTile(
                      title: Text(list[index]), trailing: const Icon(Icons.delete)),
                );
              }),
        );
      }
    }
    
    2、ScaleTransition
    class HomePage extends StatefulWidget {
      const HomePage({super.key});
    
      @override
      State<HomePage> createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      final globalKey = GlobalKey<AnimatedListState>();
      List<String> list = ["第一条数据", "第二条数据"];
      @override
      void initState() {
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              list.add("这是一个数据");
              globalKey.currentState!.insertItem(list.length - 1);
            },
            child: const Icon(Icons.add),
          ),
          appBar: AppBar(
            title: const Text("AppBar组件"),
          ),
          body: AnimatedList(
              key: globalKey,
              initialItemCount: list.length,
              itemBuilder: (context, index, animation) {
                ///ScaleTransition
                return ScaleTransition(
                  scale: animation,
                  child: ListTile(
                      title: Text(list[index]), trailing: const Icon(Icons.delete)),
                );
              }),
        );
      }
    }
    

    4、 AnimatedList 删除列表

    //删除列表
    class HomePage extends StatefulWidget {
      const HomePage({super.key});
    
      @override
      State<HomePage> createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      final globalKey = GlobalKey<AnimatedListState>();
      bool flag = true;
      List<String> list = ["第一条数据", "第二条数据"];
      @override
      void initState() {
        super.initState();
      }
    
      Widget _buildItem(context, index) {
        return ListTile(
            key: ValueKey(index),
            title: Text(list[index]),
            trailing: IconButton(
              icon: const Icon(Icons.delete), // 点击时删除
              onPressed: () => _deleteItem(context, index),
            ));
      }
    
      _deleteItem(context, index) {
        if (flag == true) {
          flag = false;
          //注意:删除后需要重新 setState
          setState(() {
            // 删除过程执行的是反向动画,animation.value 会从1变为0
            globalKey.currentState!.removeItem(index, (context, animation) {
              //注意先 build 然后再去删除
              var item = _buildItem(context, index);
              list.removeAt(index);
              return FadeTransition(
                opacity: animation,
                child: item,
              );
            }, duration: const Duration(milliseconds: 500));
          }); //解决快速删除bug 重置flag
          const timeout = Duration(milliseconds: 600);
          Timer.periodic(timeout, (timer) {
            flag = true;
            timer.cancel();
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              // 增加 animation.value 会从0变为1
              list.add("这是一个数据");
              globalKey.currentState!.insertItem(list.length - 1);
            },
            child: const Icon(Icons.add),
          ),
          appBar: AppBar(
            title: const Text("AppBar组件"),
          ),
          body: AnimatedList(
              key: globalKey,
              initialItemCount: list.length,
              itemBuilder: (context, index, animation) {
                return FadeTransition(
                  opacity: animation,
                  child: _buildItem(context, index),
                );
              }),
        );
      }
    }
    

    相关文章

      网友评论

          本文标题:Flutter 组件之 AnimatedList 动态列表

          本文链接:https://www.haomeiwen.com/subject/mcykpdtx.html