I'm Building Taskito
I'm Building Taskito
Get it on Google Play Download on the App Store

ViewPager Animations


Meaningful transitions and animations makes the UI more elegant. Now, I’m no UI expert but I can say when I like a thing better than the other. Well, this post is about that. Adding animations is good but adding intuitive animations is better. In the previous post, I talked about view position in ViewPager - ViewPager cards inspired by “ViewPager class inspired by Duolingo”.

Let’s take the same example and add some in and out animations based on actions. When the data is available, we’ll show that cards are entering from the bottom and when the user presses back, cards go back to the bottom of the screen.

Animations

public class CustomAnimationUtils {
public static void animateY(@NonNull View view, int startY, int endY, int duration) {
animateY(view, startY, endY, duration, new AccelerateDecelerateInterpolator());
}
public static void animateY(@NonNull View view, int startY, int endY, int duration,
@NonNull Interpolator interpolator) {
view.clearAnimation();
view.setTranslationY(startY);
ViewCompat.animate(view).translationY(endY)
.setInterpolator(interpolator)
.setDuration(duration)
.withLayer()
.setListener(null)
.start();
}
}

Our strategy is to show that view is coming from bottom of the screen and fixes at its position. Initially, we’ll set translationY to a high value so that we do not have to worry about long screens or tablets. Next, we want to animate translationY property and get it to 0. We should specify duration and interpolator by some trial and error and see which fits the best.

With our helper methods, animation call is just one line code.

private void animateIn() {
// start translationY - 2000
// final translationY - 0
// Duration - 1 sec
CustomAnimationUtils.animateY(viewPager, 2000, 0, 1000);
}
private void animateOut() {
// start translationY - 0
// final translationY - 2000
// Duration - 1 sec
CustomAnimationUtils.animateY(viewPager, 0, 2000, 1000);
}
Animate In Animate Out
viewpager animate in viewpager animate out

Simple. Works well. But we can do better.

It would be better if we could animate each page differently so that it would look like second page came after the first page. To achieve this, we need those views. In my code, I have modified my PagerAdapter to store the views based on the index. I think you could simply do ViewPager.getChildAt(0) to get the first view. So once we get the first and second view, we can make the second view come in a bit late.

The same can be performed for animating out.

private void animateIn() {
// Get view from PagerAdapter or ViewPager -> viewPager.getChildAt(0)
View page0 = adapter.getViewAt(0);
View page1 = adapter.getViewAt(1);
// Make second page appear slower than the first one
// so that user notices there are more pages
CustomAnimationUtils.animateY(page0, 2000, 0, 500);
CustomAnimationUtils.animateY(page1, 3000, 0, 700);
}
private void animateOut() {
int position = viewPager.getCurrentItem();
View currentPage = adapter.getViewAt(position);
CustomAnimationUtils.animateY(currentPage, 0, 2000, 400, new AnticipateInterpolator(1));
if (position != 0) {
View previousPage = adapter.getViewAt(position - 1);
CustomAnimationUtils.animateY(previousPage, 0, 2000, 500);
}
if (position < adapter.getCount() - 1) {
View nextPage = adapter.getViewAt(position + 1);
CustomAnimationUtils.animateY(nextPage, 0, 2000, 500);
}
}
Animate In Animate Out
viewpager animate in viewpager animate out

I’m sure there are much better animations and transitions that we can implement. Well, this is just a start.

P.S. I should study Google’s guidelines for Motion and Movement in particular.

Playing around with Android UI

Articles focusing on Android UI - playing around with ViewPagers, CoordinatorLayout, meaningful motions and animations, implementing difficult customized views, etc.

Read next