美文网首页
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