Flutter AnimatedList 实现动态列表

发布时间 2023-12-21 16:46:24作者: angelwgh
import 'dart:async';

import 'package:flutter/material.dart';

final GlobalKey _globalKey = GlobalKey();

class MyAnimatedList extends StatelessWidget {
  const MyAnimatedList({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AnimatedList'),
      ),
      body: AnimatedListBody(
        _globalKey,
      ),
      floatingActionButton: FloatingActionButton(onPressed: () {
        var state = _globalKey.currentState as _AnimatedListBodyState;
        state.insterItem();
      }),
    );
  }
}

class AnimatedListBody extends StatefulWidget {
  const AnimatedListBody(Key? key) : super(key: key);

  @override
  State<AnimatedListBody> createState() => _AnimatedListBodyState();
}

class AnimateItem {
  String title;
  GlobalKey key; //用来获取需要删除的组件
  AnimateItem(this.title) : key = GlobalKey();
}

class _AnimatedListBodyState extends State<AnimatedListBody> {
  // 定义一个 [AnimatedListState]类型的key
  final _animateGlobalKey = GlobalKey<AnimatedListState>();
  List<AnimateItem> list = [];
  int count = 0;
  // 插入数据
  void insterItem() {
    list.add(AnimateItem('第$count条数据'));
    count++;
    _animateGlobalKey.currentState!.insertItem(list.length - 1);
  }

  // 删除数据
  // 删除的状态,避免重复点击报错
  Map<GlobalKey, bool> delStateMap = {};
  void removeItem(int index, GlobalKey key) {
    if (delStateMap[key] != true) {
      delStateMap[key] = true;

      var item = key.currentWidget;
      list.removeAt(index);
      _animateGlobalKey.currentState!.removeItem(
        index,
        (context, animation) {
          return FadeTransition(
            opacity: animation,
            child: item,
          );
        },
      );

      Timer.periodic(const Duration(milliseconds: 1000), (timer) {
        delStateMap.remove(key);
        timer.cancel();
      });
    }
  }

  Widget _itemBuild(
      BuildContext context, int index, Animation<double> animate) {
    final item = list[index];
    return FadeTransition(
      opacity: animate,
      child: ListTile(
        key: item.key,
        title: Text(item.title),
        trailing: IconButton(
          icon: const Icon(Icons.close),
          onPressed: () {
            removeItem(index, item.key);
          },
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedList(
      key: _animateGlobalKey,
      initialItemCount: list.length,
      itemBuilder: _itemBuild,
    );
  }
}