How to add Card Flip Animation to your Android App
Read how to make your Android App more delightful
using Card Flip Animation.
For a long time, I’ve tried to implement Card Flip Animation, but every tutorial or source code I’ve found didn’t explain “magic” numbers in XML animation files. Out of nowhere wild hackathon appeared!
On our company’s latest hackathon we decided to develop an app for Planning Poker. As you can guess Flip Animation was very important to make our app delightful. I was chosen to create UI and it was a nice opportunity to dive into Flip Animation. In this blog post, I will explain everything I have learned about it.
Card layouts
At first, let’s create a simple layout with a front of a card:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:tint="@color/cardFront" android:padding="16dp" android:src="@drawable/rectangle"/> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/front" android:textColor="@color/white" style="@style/Base.TextAppearance.AppCompat.Display1" android:gravity="center"/> </FrameLayout> |
and put it to activity layout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="blog.droidsonroids.pl.blogpost.MainActivity" android:onClick="flipCard"> <FrameLayout android:id="@+id/card_front" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <include layout="@layout/card_front" /> </FrameLayout> </FrameLayout> |
Animation XML
After that, create the first animation XML.
1 2 3 4 5 6 7 8 | <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:valueFrom="0" android:valueTo="180" android:propertyName="rotationY" android:duration="@integer/anim_length" /> </set> |
This simple animation just rotates the view around Y axis from 0 to 180 degree and it is what we need for first part of our animation. As it is shown below, animation disappears half-way through, but I will explain later how to fix it.
The second part of the animation is just “opposite” to what we’ve just created. So, I changed two values in our XML file
1 2 3 4 5 6 7 8 | <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:valueFrom="-180" android:valueTo="0" android:propertyName="rotationY" android:duration="@integer/anim_length" /> </set> |
and see what happened:
-180 value causes the view to flip immediately and start rotating it to its natural position. The sign decides about the direction of motion. Feel free to experiment and change values for better understanding a problem and don’t worry about that ugly glitch at animation start because that will be unnoticeable for a user.
To make the whole animation, we need to create two XML files for enter and exit animation and fix disappearing card on half-way through animation. To fix it we just need to change camera distance. Camera distance is the length between animated view and a “virtual” eye. Changing that distance affects the perspective distortion.
LET’S TALK ABOUT YOUR APP
We’re 100% office based team with 7-years’ experience
in mobile & web app development
Camera distance
In our case distance is just to small and Flipping Animation crosses the “virtual line” and disappears. To fix it we just need to increase that distance. The default distance is different on various devices. According to Android documentation, if you want to specify a distance that leads to visually consistent result across various devices use that formula:
1 2 | float scale = context.getResources().getDisplayMetrics().density; view.setCameraDistance(distance * scale); |
I set the distance to 8000 to make animation perspective less distorted.
Whole animation
A second thing we need to do is hide/show view in half of the animation, to achieve this, simply add following lines
1 2 3 4 5 | <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:duration="0" /> |
to every animation file. Let’s take a look at out_animation.xml (animation of foreground view).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:valueFrom="0" android:valueTo="180" android:propertyName="rotationY" android:duration="@integer/anim_length" /> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:startOffset="@integer/anim_length_half" android:duration="1" /> </set> |
This animation rotates view from a natural position to mirrored position around the Y-axis and hides it half-way.
A half-way animation is achieved by setting startOffset for half of the time of the whole animation. Next in_animation.xml (animation of background view) looks almost the same:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:duration="0" /> <objectAnimator android:valueFrom="-180" android:valueTo="0" android:propertyName="rotationY" android:repeatMode="reverse" android:duration="@integer/anim_length" /> <objectAnimator android:valueFrom="0.0" android:valueTo="1.0" android:propertyName="alpha" android:startOffset="@integer/anim_length_half" android:duration="0" /> </set> |
At first, a view is set to invisible, then animation starts and half-way through it, the view is set to visible.
Result
This is what we achieve by combining two animations:
Wrap up
I hope that after reading this post you will be no more afraid of implementing a Flip Animation and your apps will look more delightful than ever.
The project can be found on DroidsOnRoids Github in FlipAnimation-Android repository.
Ready to take your business to the next level with a digital product?
We'll be with you every step of the way, from idea to launch and beyond!
This is great but how do you handle configuration changes? I’ve followed your sample code, but when I rotate the screen and click the “card to flip” it crashes with no helpful error log
What if you wanted to do a flip animation of items in a recyclerview much like how flipboard works? How would that be achieved?
With me, I had issues with flicker of nested items. This was solved using hardware acceleration ( see http://stackoverflow.com/a/26118166/389649 )
Awesome
thank you.
thank