How to create animated accordion menu from React native? Here we are going to use Flatlist for our accordion menu with react native reanimated v2. Accordion menu views are commonly used when building react native applications and React web applications. In our example, we are going to create react native accordion with arrow.
What we are going to build is an animated accordion list that looks like this:
Now let’s get started working on the accordion menu.
Things We are goings to Cover in this section
- Creating a list view from react native flatlist.
- Animate arrow when tapping on the list item.
- Create smooth layout animation to show/hide the content.
Now let’s see why I choose react native reanimated library over native APIs.
Cons of existing Layout animated APIs from react native module
- They Work Globally. For example, when working with redux store suppose we want to change a state so that layout changes. So we have no control over which screen the animation should happen on.
- They are not customizable enough. But with react native reanimated we have a number of various animations that can be done accordingly and are customizable to your requirement.
- LayoutAnimation for android is still at the experimental level so I would personally recommend using the reanimated library.
What packages do you need to create animated accordion menu
Make Sure to install react native svg transformer also because if this is not installed then the SVG will not render properly. Just install react native svg then install react native svg transformer. Then add the below to your metro.config.js file.
note: If you are not willing to use SVG just you need to install react-native-reanimated. You can use png as you wish.
let’s dive into the code.
As you can see in the above code we have declared our data array and we have used flatlist to render our list. In the renderItem we have created a new component in which we are going to do all our animations for collapsible view.
Let’s look at the code for the AccordionItem component.
Accordion Item(Component)
We have declared a shared value to set the initial value for arrow animation. Shared values are nothing but it’s the same as the value we are using on Animated API(Animated.value
) React native. The only thing is these shared values are designed to read and write from the UI thread so the performance will be increased with smooth animations. For more information on shared values in React Native, you can prefer this.
How toggleButton function works?
When we tap on the list item we need to set the shared value. So if the current shared value is 0 then set it as 1 and vice versa. Also, we have not set the shared values directly we have added withTiming
which are coming in the reanimated module. So that the shared values change accordingly between the time frame. withTiming
allows parameters duration
, easing
. Here we have given 500 milliseconds for the duration. In 500 milliseconds the shared values change periodically. And also for Easing for how the animation should happen.
You can find a visualization of some common easing functions at http://easings.net/.
Process for our animated accordion menu
Here we are going to;
- Animate arrow based on the shared value
- Animate View height from the information that we get from
onLayout
function.
For all our animation styles we are going to use useAnimatedStyle
hook from react native reanimated.
Animate arrow
So we need to animate the arrow. We can wrap that arrow SVG from Animated.View
the component and there we can add our animation styles. The animation for the list item we have added here is rotating the list arrow to 90 degrees. So we have used interpolation and when the shared value changes from 0 to 1 we have provided the output from 0 to 90. So that it will change the direction of the arrow.
Animate height
Let’s check how we can animate our view height when the shared value changes,
We need to set an initial value for the height of our bodyView for once. So we know what value to return when we open the list item. But, we can’t use the height of the animated view. This is because we are going to set the bodyHeight
using the onLayout
prop of View
. For an animated view, this is called many times while the view is animating! This is not good for us, we just want to set it once.
To fix this we can nest another regular view in our animated view which can have a constant height. We can then use this view’s height for the value of bodyHeight
.
onLayout
takes a function with an event parameter. We access the height of the component via event.nativeEvent.layout.height
. When the onLayout
calls we set the height to our state. then we can interpolate our height when the shared.value
changes as you can see above. So when the shared.value
changes from 0 to 1 we will animate our height from 0 to bodySectionHeight
.
That’s it for the animated accordion list.
If you have any questions, or comments or think that there is a better way to implement this — feel free to comment here or reach out at [email protected]
4 comment(s)
Lily Alberts
Bookmarked, so I can continuously check on new posts! If you need some details about Airport Transfer, you might want to take a look at […] Read MoreBookmarked, so I can continuously check on new posts! If you need some details about Airport Transfer, you might want to take a look at YR4 Keep on posting! Read Less
JEHillert
I tried to make a nestable accordion component and kept getting this weird bounce. Top level accordion was fine. Just in the child […] Read MoreI tried to make a nestable accordion component and kept getting this weird bounce. Top level accordion was fine. Just in the child accordions, when collapsing, the title would bounce down to the bottom and then up again. Fix was just to remove `bottom: 0` property from the bottomContainer styles. I only tested on Android, so iOS may not need it, or would need some other adjustment. Read Less
Pasindu Navod
to JEHillert
Can you share me the git hub repo or the code snippet so i can check?
jehillert
This is working vastly better than the first recipe for an animated accordion that I tried. The code is small enough that I can […] Read MoreThis is working vastly better than the first recipe for an animated accordion that I tried. The code is small enough that I can adapt and customize without too much trouble. thank you sir. Read Less