How to Achieve Effortless List Item Animation and Reordering in Flutter

Explore AnimatedReorderableListView for List Item Animation with Drag to Reorder in Listview and GridView in Flutter.
Feb 29 2024 · 5 min read

Background

In a world full of Flutter app creation, making things easy and fun for users is super important. 

Recently, I needed to create a list where you could drag items around, and I wanted it to look cool with smooth animations. The built in ReorderableList of Flutter is good, but it lacked the fancy animations I was hoping for. 

Well, the  animated_reorderable_list library is designed to elevate user experience by providing drag and drop functionality with some really neat animations to make your app more lively.

In this article, we’ll explore animated_reorderable_list and will see how easy it is to add animations with the drag-and-drop function for both Listview and GridView.

 What we’ll implement in this blog?

You can find the full source code here and the library on pub.dev.


Sponsored

We are what we repeatedly do. Excellence, then, is not an act, but a habit. Try out Justly and start building your habits today!


Key Features

Let’s take a closer look at the features of the library.

Smooth Transition

In Flutter AnimatedList, While inserting or removing items, the below items jump instead of making a smooth transition. So, this library provides a smooth transition while adding or removing items.

Drag and Drop

This library provides drag and drop support for both Listview and GridView and allows users to reorder items with animations.

Built in Animation Support

There is built in support for some animations like ScaleIn, FadeIn, and SizeIn.

Simple Implementation

In Flutter AnimatedList, updating the UI requires calling insertItem and removeItem methods through listState using a key. With this library, You can update the UI by just updating a list like ListView.

Enhanced Performance

This library is great for larger lists. it optimizes performance by rendering items only when they enter the viewport.


How to Implement?

Now, let’s get practical and see how you can use animated_reorderable_list in your own Flutter project. 

Add Dependency

Add the following dependency in pubspec.yaml file.

animated_reorderable_list: <latest version>

Getting Started

This is a simple Todo app where we are going to implement animations while adding or removing items from the list.

For simplicity, we will not implement UI from scratch. You can find the full source code here.

class ActivityPage extends StatefulWidget {
  const ActivityPage({super.key});

  @override
  State<ActivityPage> createState() => _ActivityPageState();
}

class _ActivityPageState extends State<ActivityPage> {
....

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.black,
        appBar: AppBar(
       ....
        ),
        body: ListView.builder(
          padding: const EdgeInsets.all(16),
          itemCount: activities.length,
          itemBuilder: (BuildContext context, int index) {
            final activity = activities[index];
            return ActivityCard(
              activity: activity.activity,
              why: activity.why,
              color: Colors.primaries[index % Colors.primaries.length].shade50,
              selected: activity.selected,
              onChanged: (value) => _handleOnChanged(value, activity),
            );
          },
        ),
        floatingActionButton: FloatingActionButton(
          backgroundColor: Colors.orangeAccent,
          onPressed: _displayDialog,
          child: const Icon(Icons.add, color: Colors.black,),
        ),
      ),
    );
  }

Run the app and see how it looks.

Implement Animations

Now, we are going to use the AnimatedListView, to implement animations while adding or removing the item from the list.

class _ActivityPageState extends State<ActivityPage> {
....

  @override
  Widget build(BuildContext context) {
    return SafeArea(
     ....
     
//Replace Listview.builder with AnimatedList 

        body: AnimatedListView(
          padding: const EdgeInsets.all(16),
          
//Pass List of items to be displayed

          items: activities,
          itemBuilder: (BuildContext context, int index) {
            final activity = activities[index];
            return ActivityCard(
              key: Key(activity.activity), //Add unique Key for each item
              activity: activity.activity,
              why: activity.why,
              color: Colors.primaries[index % Colors.primaries.length].shade50,
              selected: activity.selected,
              onChanged: (value) => _handleOnChanged(value, activity),
            );
          },
        ),
       ....
      ),
    );
  }

....
}

Here, we just Replaced ListView.builder with AnimatedListView. It takes a list of items and  itemBuilder function to build each item in the list. We have to pass a key to uniquely identify each item.

Let's see what it looks like,

You can see smooth transitions and fade in animation. It’s because default animations are set to FadeIn.
Let’s customize it.

Customizing Animations


AnimatedListView(
  padding: const EdgeInsets.all(16),
  items: activities,
  itemBuilder: (BuildContext context, int index) {
....
  },
 enterTransition: [
   FadeIn(
    duration: const Duration(
      seconds: 2,
     ),
    ),
    ScaleIn(duration: const Duration(seconds: 2), curve: Curves.bounceIn),
   ],
 exitTransition: [SlideInLeft()],
),

enterTransition: Specifies the enter tradition for items when they are added to the list.

exitTransition: Specifies the exit tradition for items when they are removed from the list.

Here we can add a List of animations that run concurrently, However, for customizations such as introducing delays, extending animation duration, or sequencing animations after one another, we can customize animation also.

one thing, we keep in mind is that if we add insertDuration or removeDuration then it will override the duration of a specific animation.

Implement Drag to Reorder

Now, let’s implement drag to reorder. For that, we can use ReorderableAnimatedListView which supports both drag and drop and animations.

body: AnimatedReorderableListView(
  padding: const EdgeInsets.all(16),
  items: activities,
  itemBuilder: (BuildContext context, int index) {
    ....
  },
  onReorder: (int oldIndex, int newIndex) {
    setState(() {
      final activity = activities.removeAt(oldIndex);
      activities.insert(newIndex, activity);
    });
  },
  ....
),

We’ve replaced AnimatedListView with AnimatedreorderableListView and add onReorder callback to reorder the items in the list.

Isn't it pretty easy to implement a Reorderable list with animation?

Animated Reorderable Gridview


Let’s add it for GridView. AnimatedGridview is similar to AnimatedListView and AnimatedReorderableGridView is similar to AnimatedReorderableListview.

body: AnimatedReorderableGridView(
  padding: const EdgeInsets.all(16),
  items: activities,
  itemBuilder: (BuildContext context, int index) {
   ....
  },
    sliverGridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 2
    ),
  onReorder: (int oldIndex, int newIndex) {
    setState(() {
      final activity = activities.removeAt(oldIndex);
      activities.insert(newIndex, activity);
    });
  },
  ...
),

Here, AnimatedReorderableGridView is similar to created above, but it takes sliverGridDelegate to configure the layout of the grid.

Now, run the app,

Customize Builder

// A custom builder that is for inserting items with animations. 

insertItemBuilder: (Widget child, Animation<double> animation) { 
     return ScaleTransition( scale: animation, child: child);
  },

// A custom builder that is for removing items with animations.

removeItemBuilder: (Widget child, Animation<double> animation){
     return ScaleTransition(scale: animation, child: child);
  },

insertItemBuilder and removeItemBuilder are used as custom builders for inserting and removing items from the list. It takes two parameters — child, which is the widget being inserted or removed, and animation, an animation controller for the animation.

Well, now you may be thinking that it’s pretty easy, right? I bet it is!

Happy coding! 🤖✍🏻


Conclusion

In this article, we’ve explored animated_reorderable_list library and learned how it simplifies the implementation of drag-and-drop functions within both ListView and GridView As you explore, feel free to share any problems you run into, so we can work together to make the library even better.


Useful Articles


sneha.s image
Sneha Sanghani
Flutter developer | Writing a Blog on Flutter development


sneha.s image
Sneha Sanghani
Flutter developer | Writing a Blog on Flutter development

footer
Subscribe Here!
Follow us on
2024 Canopas Software LLP. All rights reserved.