banner
MiniKano

MiniKano

This is MiniKano's blog based on Blockchain technology. 新手,请多关照~
github

Using AnimatedList to implement adding and deleting list items.

AnimatedList is a stateful widget, and its corresponding state type is AnimatedListState.

The structure of AnimatedList is as follows:

const AnimatedList({
  Key? key,
  required Widget Function(BuildContext, int, Animation<double>) itemBuilder, // Data builder
  int initialItemCount = 0, // Total length of initial data
  Axis scrollDirection = Axis.vertical, // Scroll direction
  bool reverse = false, // Whether to display from bottom to top
  ScrollController? controller, // Scroll controller, optional, controls the scroll position of the list
  bool? primary, // Whether to associate with the parent scroll
  ScrollPhysics? physics, // How to respond to user actions
  bool shrinkWrap = false,
  EdgeInsetsGeometry? padding, // Padding
  Clip clipBehavior = Clip.hardEdge,
})

There are two methods in the state to add and remove elements in the list:

Note that if the list is bound to a data source list, you cannot directly achieve the effect of updating the list by removing or adding elements. You also need to execute the following methods:

// Insert element
void insertItem(
    int index, 
    {Duration duration = _kDuration}
)
// Remove element
void removeItem(
  int index,
  Widget Function(BuildContext, Animation<double>) builder, {
  Duration duration = _kDuration,
})

When adding or removing, the specified animation will be displayed.

When using insertItem and removeItem, you usually need to use a globalKey, but the globalKey needs to specify the generic type in order to call the methods to add and remove list elements:

final globalKey = GlobalKey<AnimatedListState>();

To add an element, you only need to:

list.add("New data");
globalKey.currentState!.insertItem(list.length - 1);

Removing an element is more complicated because you need to display the animation when the element leaves and then delete the corresponding entry in the data source:

Usually, we need to create a _buildItem method to dynamically create child elements. When executing removeItem, first create an identical child element in the callback, fade it out using animation, and finally delete the data in the data array.

// Remove element
_delItem(index) {
    globalKey.currentState!.removeItem(index, (context, animation) {
        // Get the element to be removed and fade it out
        var removeItem = _buildItem(index);
        return FadeTransition(
            // Execute animation
            opacity: animation,
            child: removeItem,
        );
    });
    list.removeAt(index); // Delete data from the array
}

Complete code#

// AnimatedList
class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // Define a globalKey
  final globalKey = GlobalKey<AnimatedListState>();
  List<String> list = ["First data", "Second data"];
  bool flag = true;
  Widget _buildItem(index) {
    return ListTile(
      title: Text(list[index]),
      trailing: IconButton(
        icon: const Icon(Icons.delete),
        onPressed: () {
          // Execute deletion
          _delItem(index);
        },
      ),
    );
  }

  // Remove element
  _delItem(index) {
    globalKey.currentState!.removeItem(index, (context, animation) {
      // Get the element to be removed and fade it out
      var removeItem = _buildItem(index);
      list.removeAt(index); // Delete data from the array
      return FadeTransition(
        // Execute animation
        opacity: animation,
        child: removeItem,
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("kano")),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        // This will not work on AnimatedList by directly manipulating the list
        onPressed: () {
          // setState(() {
          //   list.add("New data");
          // });
          /// Use the insertItem method in AnimatedList
          list.add("New data");
          globalKey.currentState!.insertItem(list.length - 1);
        },
      ),
      // Animated list with animation
      body: AnimatedList(
        key: globalKey,
        initialItemCount: list.length,
        itemBuilder: (context, index, animation) {
          // Fade transition opacity enters from 0 to 1 and exits in reverse
          return FadeTransition(opacity: animation);
          // Scale transition
          // return ScaleTransition(scale: animation);
        },
      ),
    );
  }
}

Demo#

1-3[1].gif

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.