Using Transitions API to Create Android App Animations
Azoft Blog Using Transitions API to Create Android App Animations

Using Transitions API to Create Android App Animations

By Sergey Grigoriev on May 21, 2015

Create android app animations using transitions api

Creating animation for Android

Despite the high demand and prevalence of animation in mobile apps, developers point out that the process of creating animation for Android OS has always been a challenge. While iOS has long provided useful tools for working with animation, solutions for Android that help optimize developers’ work are relatively new.

But surely these animation tools have greatly simplified the lives of programmers. Such tools are convenient for creating a variety of app animations. Instead of animating individual screens, developers can animate the so-called Scenes, while transitions are generated automatically by Transition API. And that's only the tip of the possibilities iceberg! The information I’m going to share here will definitely be useful to anyone developing apps for the world's most popular mobile OS.

Transitions API: How does it work?

Even in Android 4.0, there was an early solution to the animation problem: the flag animateLayoutChange for ViewGroup. However, this tool was not flexible enough and could not provide developers with complete control over the transitions. But starting Android 4.4 KitKat and beyond, Transitions API has been implemented. Transitions API also exists in support library, so it can be used to create animation for almost any device with Android OS.

In KitKat Transition API, concepts such as Scene and Transition between scenes appear. In order to determine the root layout, Scene root was introduced. All changes in the scenes happen inside the Scene root. At the same time, the Scene itself is essentially a wrapper over the ViewGroup, describing its own status and all the statuses of the View objects. Transition is a mechanism that allows to read View parameters, which change between the Scenes, and generate animations to make the changes smooth.

Transition Frameworks in KitKat Transition API provides the following features to create animations:

  • Group-level animations: the ability to animate the whole hierarchy of View objects. Developer points ViewGroup and animations automatically apply to each of its elements
  • Transition-based animation
  • Built-in animations: simple animations such as dissolution, darkening, resizing, movement, etc.
  • Resource file support: developers can create animations from resource files without writing code
  • Lifecycle callbacks: provides all the necessary methods of control over the playback

Despite all of its advantages, this new method also has some limitations:

  • It may falter if applied to the most complex SurfaceView or TextureView, which do not work in UI thread
  • AdapterView, such as ListView, when you have to animate individual elements from the list
  • Occasionally, there are problems with synchronization when you try to resize a TextView: the font may be displayed in the next scene before the changing of other objects is finished

However, these restrictions aren’t very significant. In practice, situations when you might need to apply an animation to SurfaceView, for instance, are extremely rare.

Consider the below examples of animation in Transition Frameworks:

Creating Scene from Resource file:

res/layout/activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/master_layout">
    <TextView
        android:id="@+id/title"
        ...
        android:text="Title"/>
    <FrameLayout
        android:id="@+id/scene_root">
        <include layout="@layout/scene_first" />
    </FrameLayout>
</LinearLayout>

res/layout/scene_first.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView
        android:id="@+id/text_view1
        android:text="Text Line 1" />
    <TextView
        android:id="@+id/text_view2
        android:text="Text Line 2" />
</RelativeLayout>

res/layout/scene_second.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scene_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView
        android:id="@+id/text_view2
        android:text="Text Line 2" />
    <TextView
        android:id="@+id/text_view1
        android:text="Text Line 1" />
</RelativeLayout>
Scene mFirstScene;
Scene mSecondScene;

// Create the scene root for the scenes in this app
mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);

// Create the scenes
mFirstScene = 
    Scene.getSceneForLayout(mSceneRoot, R.layout.scene_first, this);
mSecondScene =
    Scene.getSceneForLayout(mSceneRoot, R.layout.scene_second, this);

Creating Scene from Code:

// Obtain the scene root element
mSceneRoot = (ViewGroup) findViewById(R.id.scene_root);

// Obtain the view hierarchy to add as a child of
// the scene root when this scene is entered
mViewHierarchy = (ViewGroup)findViewById(R.id.scene_conteiner);

// Create a scene
Scene scene = new Scene(mSceneRoot, mViewHierarchy);

Creating Transitions from Resource file:

res/transition/fade_transition.xml

<fade xmlns:android="http://schemas.android.com/apk/res/android" />

Transition mFadeTransition =
        TransitionInflater.from(this).
        inflateTransition(R.transition.fade_transition);

And also from code:

Transition mFadeTransition = new Fade();

You can create entire animation sets. For example: move, resize, and darken your object simultaneously:

In resource:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="sequential">
    <fade android:fadingMode="fade_out" />
    <changeBounds />
    <fade android:fadingMode="fade_in" />
</transitionSet>

In code:

TransitionSet set = new TransitionSet();
set.addTransition(new Fade())
    .addTransition(new ChangeBounds())
    .addTransition(new AutoTransition());

Apply the animation to a certain View object, not the whole Scene, if you need:

<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeBounds />
    <fade android:fadingMode="fade_in" />
        <targets>
            <target android:targetId="@id/transition_title" />
        </targets>
    </fade>
</transitionSet>

Transition Manager is created by a single line of code. It is needed to write all the Scenes and Transitions in one place. Transition Manager allows to speed up the work and control all animations more effectively.

res/transition/transition_manager.xml

<transitionManager xmlns:app="http://schemas.android.com/apk/res-auto">
    <transition
        app:fromScene="@layout/scene_reg1"
        app:toScene="@layout/scene_reg2"
        app:transition="@transition/trans_reg1_to_reg2" />
    <transition
        app:fromScene="@layout/scene_reg2"
        app:toScene="@layout/scene_reg3"
        app:transition="@transition/trans_reg2_to_reg3" />
    ...
</transitionManager>
TransitionManager transitionManager = TransitionInflater.from(context)
    .inflateTransitionManager(R.transition.transition_manager, sceneRoot);

How to run Scenes? Easy!

With custom Transitions:

mTransitionManager.transitionTo(scene);

or

TransitionManager.go(scene, fadeTransition);

With default Transitions:

TransitionManager.go(scene);

Or even without Transitions:

scene.enter();

You can also use Transitions without creating Scenes:

res/layout/activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <EditText
        android:id="@+id/inputText"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    ...
</RelativeLayout>

MainActivity.java

private TextView mLabelText;
private Fade mFade;
private ViewGroup mRootView;

// Load the layout
setContentView(R.layout.activity_main);

// Create a new TextView and set some View properties
mLabelText = new TextView();
mLabelText.setText("Label").setId("1");

// Get the root view and create a transition
mRootView = (ViewGroup) findViewById(R.id.mainLayout);
mFade = new Fade(IN);

// Start recording changes to the view hierarchy
TransitionManager.beginDelayedTransition(mRootView, mFade);

// Add the new TextView to the view hierarchy
mRootView.addView(mLabelText);

// When the system redraws the screen to show this update,
// the framework will animate the addition as a fade in

Using the intuitive interface of TransitionListener, you can control the playback of each animation element:

public static interface TransitionListener {
   void onTransitionStart(Transition transition);

   void onTransitionEnd(Transition transition);

   void onTransitionCancel(Transition transition);

   void onTransitionPause(Transition transition);

   void onTransitionResume(Transition transition);
}

Create your own animation. For example, you can change background color of the View object:

public class ChangeColor extends Transition {

   private static final String PROPNAME_BACKGROUND = 
"customtransition:change_color:background";

   private void captureValues(TransitionValues values) {
       values.values.put(PROPNAME_BACKGROUND, values.view.getBackground());
   }

   @Override
   public void captureStartValues(TransitionValues transitionValues) {
       captureValues(transitionValues);
   }

   @Override
   public void captureEndValues(TransitionValues transitionValues) {
       captureValues(transitionValues);
   }
  
   @Override
   public Animator createAnimator(ViewGroup sceneRoot, 
                                  TransitionValues startValues, 
                                  TransitionValues endValues) {
       if (null == startValues || null == endValues) {
           return null;
       }
      
       final View view = endValues.view;
      
       Drawable startBackground = 
           (Drawable) startValues.values.get(PROPNAME_BACKGROUND);
       Drawable endBackground = 
           (Drawable) endValues.values.get(PROPNAME_BACKGROUND);
      
       ColorDrawable startColor = (ColorDrawable) startBackground;
       ColorDrawable endColor = (ColorDrawable) endBackground;

       if (startColor.getColor() == endColor.getColor()) {
           return null;
       }

       ValueAnimator animator = ValueAnimator.ofObject(new ArgbEvaluator(),
               startColor.getColor(), endColor.getColor());
       animator
           .addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
           @Override
           public void onAnimationUpdate(ValueAnimator animation) {
               Object value = animation.getAnimatedValue();
               if (null != value) {
                   view.setBackgroundColor((Integer) value);
               }
           }
       });
       return animator;
   }

}

Intermediate values are generated automatically, that’s why in our example the color gradually changes from red to blue. This method opens up opportunities to create a variety of custom animations and transitions: imagination of developers is limited only to the requirements of a particular project.

Why should you care?

Fast speed and simplicity of the process of creating animations adds drive to the development of mobile apps. Azoft team is very enthusiastic about the Transitions API and we are already using this method in our projects. The ability to create animations using Scenes, saving time and effort, has been helpful to both our developers and clients, who can get the results faster.

Tell us about your experience creating animation for Android. Do you use Transitions API? What are this method’s pros and cons? What other tools do you use to create animation for mobile apps?

VN:F [1.9.22_1171]
Rating: 4.6/5 (12 votes cast)
VN:F [1.9.22_1171]
Rating: +4 (from 8 votes)
Using Transitions API to Create Android App Animations, 4.6 out of 5 based on 12 ratings



Request a Free Quote
 
 
 

Please enter the result and submit the form