Skip to content

Latest commit

 

History

History
114 lines (101 loc) · 3.05 KB

File metadata and controls

114 lines (101 loc) · 3.05 KB

AnimatedList

A scrolling container that animates items when they are inserted or removed.

This widget's AnimatedListState can be used to dynamically insert or remove items. To refer to the AnimatedListState either provide a GlobalKey or use the static of method from an item's input callback.

This widget is similar to one created by ListView.builder.

Example

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

  @override
  State<ExAnimatedList> createState() => _ExAnimatedListState();
}

class _ExAnimatedListState extends State<ExAnimatedList> {
  var data = <String>[];
  int counter = 5;

  final globalKey = GlobalKey<AnimatedListState>();

  @override
  void initState() {
    for (var i = 0; i < counter; i++) {
      data.add('${i + 1}');
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        AnimatedList(
          key: globalKey,
          initialItemCount: data.length,
          itemBuilder: (
            BuildContext context,
            int index,
            Animation<double> animation,
          ) {
            // animate
            return FadeTransition(
              opacity: animation,
              child: buildItem(context, index),
            );
          },
        ),
        buildAddBtn(),
      ],
    );
  }

  Widget buildAddBtn() {
    return Positioned(
      bottom: 30,
      left: 0,
      right: 0,
      child: FloatingActionButton(
        onPressed: () {
          data.add('${++counter}');
          // update key
          globalKey.currentState!.insertItem(data.length - 1);
          print('add $counter');
        },
        child: Icon(Icons.add),
      ),
    );
  }

  Widget buildItem(context, index) {
    String str = data[index];
    return ListTile(
      key: ValueKey(str),
      title: Text(str),
      trailing: IconButton(
        icon: Icon(Icons.delete),
        onPressed: () => onDelete(context, index),
      ),
    );
  }

  void onDelete(context, index) {
    setState(() {
      globalKey.currentState!.removeItem(
        index,
        (context, animation) {
          var item = buildItem(context, index);
          print('remove ${data[index]}');
          data.removeAt(index);
          return FadeTransition(
            opacity: CurvedAnimation(
              parent: animation,
              curve: const Interval(0.5, 1.0),
            ),
            child: SizeTransition(
              sizeFactor: animation,
              axisAlignment: 0.0,
              child: item,
            ),
          );
        },
        duration: Duration(milliseconds: 200),
      );
    });
  }
}