Iced Tea Labs Share to be shared

Property Animation in Android

A - Property Animation in Android Overview

Property animation in Android is very powerful, allows you to animate almost anything!
Basically, the property animation changes object’s properties value over a specified duration.

Using property animation, you can define following characteristics of the animation:

B - Compare Property Animation and View Animation

 

View Animation Property Animation
Only apply to View Be able to apply to any object
Only animate some properties of View like scaling and rotation Can animate any properties of object
Only modify where the View was drawn, not the actual View itself. For example, if you animate a View to move across the screen, the View was drawn correctly but the actual View which you can interact with is still at the old location. Modify where the object was drawn and the actual object itself
Easy to set up and write code Require more effort to implement

C - Use ValueAnimator

The ValueAnimator class lets you animate values of some type for the duration of an animation by specifying a set of int, float, or color values to animate through.

You obtain a ValueAnimator by calling one of its factory methods: ofInt(), ofFloat(), or ofObject().

private void executeAnimation() {
    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            mImgSample.setAlpha(animation.getAnimatedFraction());
        }
    });
    valueAnimator.setDuration(1500);
    valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
    valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
    valueAnimator.start();
}

 

As you can see, in order to make real animation effect to the object, we also need to define the listener for ValueAnimator.

In that listener, you can obtain the calculated value for that specific frame and apply changes to your object.

D - Use ObjectAnimator

The ObjectAnimator is a subclass of the ValueAnimator and it allows you to specify the property name of the target object.

Using ObjectAnimator, you don’t need to implement the listener implicitly because the property’s value will be updated automatically.

To create a correct ObjectAnimator, you have to define:

Example:

private void executeAnimation() {
    ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mImgSample, "rotation", 0, 360);

    objectAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
            Toast.makeText(ObjectAnimatorActivity.this, "onAnimationStart", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            Toast.makeText(ObjectAnimatorActivity.this, "onAnimationEnd", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            Toast.makeText(ObjectAnimatorActivity.this, "onAnimationCancel", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
            Toast.makeText(ObjectAnimatorActivity.this, "onAnimationRepeat", Toast.LENGTH_SHORT).show();
        }
    });

    objectAnimator.setDuration(1500);
    objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
    objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
    objectAnimator.start();
}

E - Use AnimatorSet

In case you want to group some animator together to animate it at the same time or in sequence, you can use AnimatorSet to achieve that.

private void executeAnimation() {
    ObjectAnimator fadeAnim = ObjectAnimator.ofFloat(mImgSample, "alpha", 0, 1);
    fadeAnim.setDuration(1000);
    ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(mImgSample, "rotation", 0, 360);
    rotateAnim.setDuration(1000);

    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.play(fadeAnim).before(rotateAnim);

    ObjectAnimator fadeOutAnim = ObjectAnimator.ofFloat(mImgSample, "alpha", 0);
    AnimatorSet secondAnimatorSet = new AnimatorSet();
    secondAnimatorSet.play(fadeOutAnim).after(animatorSet);
    secondAnimatorSet.start();
}

 

F - Use Interpolator

An Interpolator define the calculation of animation value over the animating time. Interpolator allows animation has a non-linear motion like acceleration and deceleration.

Android system provides some default interpolator like:

You can find out more about default Interpolator in android.view.animation package.

If you don’t like any default interpolator, you can create your own by implement TimeInterpolator interface.

private void executeAnimation() {
    ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(mImgSample, "rotation", 0, 360);
    objectAnimator.setDuration(5000);
    objectAnimator.setInterpolator(new AccelerateInterpolator());
    objectAnimator.start();
}

G - Declare Animation in XML resources

Instead of implementing the animation programmatically like above, you can declare the animation details in XML resources. This way allows you to reuse the animation and modify the animation sequence easily.

The animation XML resources are stored in res/animator/ folder.

Syntax details:

<set // Represent an AnimatorSet
  android:ordering=["together" | "sequentially"] // The order of animations in this set
  android:interpolator="@android:anim/[default_interpolator]" //The interpolator for animations in this set
  >

    <objectAnimator //Represents an ObjectAnimator
        android:propertyName="string" // The object's property to animate
        android:duration="int" // The animation duration
        android:valueFrom="float | int | color" // The property’s start value of animation
        android:valueTo="float | int | color" // The property’s end value of animation
        android:startOffset="int" // The amount of milliseconds the animation delays after animation starts
        android:repeatCount="int" // The number that animation have to repeat
        android:repeatMode=["repeat" | "reverse"] // The animation’s behaviour after reached the end of animation
        android:valueType=["intType" | "floatType"]/> //Do not specify this attribute if the value is a color

    <animator //Represents an ValueAnimator
        android:duration="int"
        android:valueFrom="float | int | color"
        android:valueTo="float | int | color"
        android:startOffset="int"
        android:repeatCount="int"
        android:repeatMode=["repeat" | "reverse"]
        android:valueType=["intType" | "floatType"]/>

    <set>
        ...
    </set>
</set>

Example:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">
    <set>
        <objectAnimator
            android:duration="1500"
            android:propertyName="x"
            android:valueFrom="50"
            android:valueTo="500"
            android:valueType="floatType" />
        <objectAnimator
            android:duration="1500"
            android:propertyName="y"
            android:valueFrom="50"
            android:valueTo="800"
            android:valueType="floatType" />
    </set>
    <objectAnimator
        android:duration="1500"
        android:propertyName="alpha"
        android:valueTo="0f" />
</set>
private void executeAnimation() {
    AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.custom_animation);
    set.setTarget(mImgSample);
    set.start();
}

 H - Demo application and Source code

Please find the complete source code of this tutorial at Github:

https://github.com/trinhlbk1991/DemoPropertyAnimation

comments powered by Disqus