#TECH

Animations in Android (Part-1: View and Property animations)

Wikipedia defines animation as the process of making the illusion of motion and change by means of the rapid display of a sequence of static images that minimally differ from each other.

view and property animation

Figure-1: Ball bouncing animation through static images

Well that’s the general idea but based on this, a plethora of animations can be produced in Android through certain predefined frameworks. This post will delve into the geeky bits of android animations. I will be describing these frameworks in theory and some implementation as well, with sample code (code can be found here).

Android provides built-in API’s to animate the graphic elements or custom 2-D and 3-D graphic elements. The basic graphic elements include the built-in views in an android activity. 2-D & 3-D elements can be drawn through widgets like canvas and drawables or a framework such as OpenGL. I will be taking you through the animations with basic graphic elements and not drawing graphics with OpenGL as that is a whole another field.

Android provides three animation systems-

  1. View Animations

  2. Property Animations

  3. Drawable Animations

View Animations:-

View animations are basic animations that alter a view’s properties to produce an animation effect. These are also called as tween animations. Four types of transformations are included which are position, size, rotation and transparency. One can define these animations in XML or through the view objects methods corresponding to the animation. For instance tweening alpha attribute of a view can be achieved through its XML implementation or through AlphaAnimation object as shown in the sample code.

View animations onClickListener (in ViewAnimations.java) :-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private void setOnClickListenerForCard(ViewHolder pHolder,final int position){

        pHolder.mLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {

                switch(position){

                    case 0:
                        //Tween alpha through XML
                        mAnimation = AnimationUtils
                                .loadAnimation(mContext, R.anim.tween);

                        //Uncomment to Tween alpha through AlphaAnimation object
//                        mAnimation = new AlphaAnimation(1,0);
//                        mAnimation.setDuration(2000);
                        break;

                    case 1:
                        mAnimation = AnimationUtils
                                .loadAnimation(mContext, R.anim.scaling);
                        break;

                    case 2:
                        mAnimation = AnimationUtils
                                .loadAnimation(mContext, R.anim.rotation);
                        break;

                    case 3:
                        mAnimation = AnimationUtils
                                .loadAnimation(mContext, R.anim.transform);
                        break;

                    case 4:
                        mAnimation = AnimationUtils
                                .loadAnimation(mContext, R.anim.custom_view_animations);
                        break;

                    default:
                        break;
                }

                v.startAnimation(mAnimation);
            }
        });
    }

 

tween.xml :-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <alpha
        android:fromAlpha="1"
        android:toAlpha="0.5"
        android:startOffset="0"
        android:duration="250"/>

    <alpha
        android:fromAlpha="0.5"
        android:toAlpha="1"
        android:startOffset="250"
        android:duration="250"/>
</set>

 
Based on the above method, this sample video will demonstrate the tween animation effects:-

Property Animations:-

Property animations system provides the framework to create more customizable animations as compared to view animations. Property animations work on the idea of changing a view’s property between certain specified values for a specified duration of time. It is also possible to define how the transition occurs from the start value to the end value i.e. linearly or non-linearly.

In addition to above points, property animations are much more robust as they animate the object unlike view animations that animate only the view. Take button view for instance, if view animation is applied to change the button’s position it will translate the view but onClick event will be triggered from its previous location only. Whereas property animations will handle the onClick event automatically as it applies the animation to the object. It is also possible to animate properties other than view attributes like the background color of view. Property animations can also be used to animate non-view objects. Property animations can also be defined through XML.

There are two different classes in property animations:-

  1. ValueAnimator
  2. ObjectAnimator

ValueAnimator:-

ValueAnimator class extends the animator class and is the base class for property animations. It provides methods to create the most customizable animations. The setup for ValueAnimator is simple. You just have to specify the start and end values along with the duration of the animation. Then in the ValueAnimator.AnimatorUpdateListener you can fetch the current animation value by calling the method getAnimatedValue(). Within the listener you set whichever attribute you want to animate to the value returned by getAnimatedValue(). Finally call your views requestLayout() method to redraw the view with updated values and you can observe the animation.

Here’s some sample code for it(ValueAnimatorFragment.java):-

animateScale():-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
private void animateScale(final View view){

        mAnimator = ValueAnimator.ofInt(0, 500);
        mAnimator.setRepeatCount(0);
        setInterpolator();
        mAnimator.setDuration(DURATION);
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {

                view.getLayoutParams().height = (int) animation.getAnimatedValue();
                view.getLayoutParams().width = (int) animation.getAnimatedValue();
                view.requestLayout();
            }
        });
        setOnAnimationEnd("scale", view);
        mAnimator.start();
    }

 
You can also set onAnimationEnd listener to make changes after the animation completes. Now you can observe a new method named setInterpolator(). It is used to set the transition behaviour for the animation. Here’s the code for it-

setInterpolator():-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
private void setInterpolator(){
        switch(mInterpolatorFlag){

            case 0:
                mAnimator.setInterpolator(new LinearInterpolator());
                break;

            case 1:
                mAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
                break;

            case 2:
                mAnimator.setInterpolator(new CustomInterpolator());
                break;

            default:
                break;
        }
    }

 
As names suggest the LinearInterpolator is responsible for linear transitions and is the default for any animation. AccelerateDecelerateInterpolator first accelerates then decelerates. CustomInterpolator extends the Interpolator interface to produce custom transitions.

This sample video will demonstrate ValueAnimator animations:-

 

ObjectAnimator :-

ObjectAnimator extends the ValueAnimator class to allow a certain level of abstraction. Here you don’t have to update the values in the AnimationUpdateListener rather you just specify the name of the property you want to animate. Property names can be like “alpha”, “scaleX”, “left” (left margin that is) etc.

Here’s some sample code(ObjectAnimatorFragment.java)-

animateTransform():-

1
2
3
4
5
6
7
8
private void animateTransform(View view){

        mAnimator = ObjectAnimator.ofInt(view, "left", 100,
                ((mSize.x)/2) - (int) getResources().getDimension(R.dimen.dp_35))
                .setDuration(2000);
        setInterpolator();
        mAnimator.start();
    }

 
This video will demonstrate similar animations but with ObjectAnimator code:-

 

Set of animations :-

Multiple property animations can be executed simultaneously with AnimatorSet class. AnimatorSet provides built-in methods to play animations either sequentially or together. Also helper methods like before(), after() and with(). AnimatorSet class works on Animator object so they cannot be applied to view animations. AnimatorSet can be defined as an object or through XML.

For view animations we can define a set of animations through XML or through AnimationSet class. View animations in sets are played simultaneously by default. It is possible to specify starOffset for each animation to introduce sequential order.

Here’s some sample code for it:-

custom_view_animations.xml:-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">


    <alpha
        android:fromAlpha="1"
        android:toAlpha="0.5"
        android:startOffset="0"
        android:duration="2000"/>

    <alpha
        android:fromAlpha="0.5"
        android:toAlpha="1"
        android:startOffset="2000"
        android:duration="2000"/>

    <scale
        android:startOffset="0"
        android:fromXScale="1"
        android:toXScale="1.2"
        android:fromYScale="1"
        android:toYScale="1.2"
        android:pivotX="50%p"
        android:pivotY="50%p"
        android:duration="2000" />

    <scale
        android:startOffset="2000"
        android:fromXScale="1.2"
        android:toXScale="1"
        android:fromYScale="1.2"
        android:toYScale="1"
        android:pivotY="50%p"
        android:pivotX="50%p"
        android:duration="2000" />

    <rotate
        android:fromDegrees="0"
        android:toDegrees="360"
        android:pivotX="50%p"
        android:pivotY="50%p"
        android:duration="2000" />

    <translate
        android:startOffset="0"
        android:fromXDelta="0%p"
        android:toXDelta="10%p"
        android:repeatMode="reverse"
        android:duration="2000"/>

    <translate
        android:startOffset="2000"
        android:fromXDelta="10%p"
        android:toXDelta="0%p"
        android:duration="2000"/>
</set>

 

This video will demonstrate the effects of this XML:-

 
Above example shows a view animations set through XML. Here’s another example through AnimationSet object:-

1
2
3
4
5
mSet = new AnimationSet(false);
mSet.addAnimation(new AlphaAnimation(0f,1f));
mSet.addAnimation(new TranslateAnimation(0f, 0f, mScreenHeight, 0f));
mSet.setDuration(1500);
mListView.startAnimation(mSet);

 
Here’s some example code for property animations set(AnimatorSetFragment.java):-

applyAnimations():-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
private void applyAnimations(View ball,View ballLayout){

        AnimatorSet animatorSet = new AnimatorSet();

        Animator animator = ObjectAnimator.ofFloat(ball,"alpha",1,0,1)
                .setDuration(1000);
        Animator animator2 = ObjectAnimator.ofFloat(ballLayout, "scaleX", 0, 0.25f,0.5f, 0.75f, 1)
                .setDuration(1000);
        Animator animator3 = ObjectAnimator.ofFloat(ballLayout, "scaleY", 0, 0.25f, 0.5f, 0.75f, 1)
                .setDuration(1000);

        //To create a transform animation
        if(ball.getId() == R.id.ball)
            createTransformDownAnimation(ballLayout);
        else
            createTransformUpAnimation(ballLayout);

        animatorSet.play(animator)
                .with(animator2)
                .with(animator3)
                .after(mTransformAnimator);

        animatorSet.start();
    }

 
createTransformUpAnimation():-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
private void createTransformUpAnimation(final View ballLayout){

        final RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) ballLayout.getLayoutParams();
        mTransformAnimator = ValueAnimator.ofInt(params.bottomMargin, params.bottomMargin +
                (int) getResources().getDimension(R.dimen.dp_250))
                .setDuration(1000);
        mTransformAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {

                params.bottomMargin = (int) animation.getAnimatedValue();
                ballLayout.requestLayout();
            }
        });
    }

 
The above shows a set of property animations through objects of both ObjectAnimator and ValueAnimator. It is also possible to create a set through XML.

animator_set.xml:-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <objectAnimator
        android:propertyName="alpha"
        android:duration="250"
        android:valueFrom="1"
        android:valueTo="0.5"
        android:startOffset="0"/>

    <objectAnimator
        android:propertyName="alpha"
        android:duration="250"
        android:valueFrom="0.5"
        android:startOffset="250"
        android:valueTo="1"/>
</set>

 

Here is a video to demonstrate a set of animations:-

 
As can be observed, the video contains three animation effects. Translation of view is through ValueAnimator and alpha & scaling through ObjectAnimator.

View and property animations are the most fundamental frameworks in android. I will be discussing about some other android animations in the next post.

 
References:-

  1. developer.android.com
  2. https://en.wikipedia.org/wiki/Animation
  3. https://github.com/tarunkohli/androidCodeSamples/tree/AnimationsInAndroid