Flutter provides some really nice scrollable widgets out of the box such as
CustomScroll view etc, but what if you want to animate your content as they enter or leave the list? How would one achieve this?
Well the answer, Animated List.
AnimatedList is a widget
Flutter provides out of the box for animating items as they are added or removed. This widget is similar in structure to
ListView.builder in the sense that both widgets have options for the initial item count as well as a builder for constructing the widgets. In fact, if you look at the
build method for
AnimatedList, it returns a
Listed below the constructor of
AnimatedList. It shows the different parameters which can be supplied to the list.
Now that you’ve been introduced, how does one use it?
To use this list, you must first start by creating a
GlobalKey of type
AnimatedListState. This key serves as the medium through which you can interact with the list.
Once you have created the key, you can now pass it to the
From the above snippet, you may also notice the builder. The builder of
AnimatedList is very similar to that of
ListView.builder except for one small difference, the extra
Animation parameter. This
animation runs every time the builder is called.
Before we could add and remove items, we need some data to play with. In this demo, we are going to keep it very simple and have a list which contains some dummy users. The
User is going to be a small model which has a person's first name, last name and a URL for their picture.
With our model and list of test users created, let’s move onto adding them to the
First, the basic skeleton of the app. We are going to have a
StatefulWidget which returns a
Scaffold is going to have an
appBar and a
body which contains our
For this demo, we are going to have a user fade in when they are added. In our
AnimatedList, we create a
ListTile and wrap it in a
animation from the
builder is then passed to the
FadeTransition for its opacity.
With the basic structure built, let’s move out attention to adding items to the list.
For this, we are going to create a new function
addUser(). This function is going to handle the adding of users to our
listData as well as inserting an item into the
AnimatedList. An important thing to note is we don't add an item to the
AnimatedList, we add them to our data. Instead, we tell the
AnimatedList to insert a new item at an index.
The above code shows how to add a new user. With an
AnimatedList, you can insert at any index. In this case, we are adding at the end of the list so we use
To add a new user to our
listData we use the
With the list updated, we need to update our
AnimatedList so that we can see the animation and the new user on the screen. For this, we need to use the
_listKey for interacting with the list.
To insert the user into the list, call
_listKey.currentState.insertItem() and pass it both the index into which you want to insert the new user and the
duration of the animation.
Finally we set the
addUser() to the
Now that we’ve covered how to add an item, it is time to wire our function to remove them.
An important thing to note about removing an item in
AnimatedList is the item is immediately removed from the list however it will remain visible on screen for the duration of time specified. Once removed, its index will no longer be passed to
Before we can actually remove an item, let’s clean up our current code. We will start by changing the way our item is built. Instead of building it directly, let’s create a new function
_buildItem(). This function will be responsible for building our
Notice our function has two parameters one of which is optional. The reason for this will become clear as we continue. Also take note of the
ValueKey around our
ListTile. Since our widgets are cached by Flutter, we need a way to uniquely identify them.
At this point, running our code will cause a crash. This is because
ValueKey uses the
== operator to compare widgets. Since we are using a custom type, we need to override the
== operator and
hashCode for our
UserModel. If you are using InteliJ, you can use
UserModel and select "generate == and hashCode". Select all three fields and hit “ok”.
Now with our refactoring complete, let’s move on to our delete function. From the code we refactored you may have noticed that we changed our
onLongPressed to use a function
deleteUser. Let us now create this function.
The above snippet shows the function for removing an item from this list. Fist, the index of the item we want to remove is passed to the function as a parameter. Next, we remove it from our
listData. At this point, the item is removed however it is still visible on screen because we did not remove it from our
AnimatedList. To do this, we use
removeItem has three parameters,
builder and an optional parameter
duration. When this method is called, it starts a reversed animation that is passed to
builder. This allows us to animate the item off-screen. For this example, we are going to both a
As a user is deleted, it is first going to fade then shrink as it is animated off-screen. As the above snippet shows, we are storing the result of
listData.removeAt(index); in a local variable
user. Next we are removing it from our
_listKey.currentState.removeItem(). We give the method the index which was passed into the function then create our builder. Here we create the build function consisting of
Animation<double>. It returns a
FadeTransition which has a
SizeTransition. For the opacity of our fade, we are using a
CurvedAnimation consisting of an
Interval and a parent of
animation. The same is done with
SizeTransition only this time the
child is our
_buildItem(). You may have noticed that we pass our local
user variable over to
_buildItem(). This is done because the removed item needs to be the same as the one which was on our list. The final piece of our puzzle is
duration. This is the length of time we want our animation to run for. In this example, we are using 600 milliseconds.
Assuming you’ve followed along, your final code show look a little something like this:
Running the above code on device yields the following results:
I hoped you enjoyed this article, if you have any questions or spot any errors or simply have a suggestion for an article, please leave a comment or reach out to me on Twitter, I am @Nash0x7E2. The full source code for this project can be found on my GitHub: https://github.com/Nash0x7E2/animated-list-demo. Also be sure to follow Flutter Community to keep up with everything as they relate to Flutter.