Thursday, December 15, 2011

Animation Two Ways Part 1

If you've been writing Android code for a while, you've probably done some work with the Animation API.  You might have noticed that Google released a new Animation API for Honeycomb.  I'm not going to talk about the details of the Animation API's.  Instead I want to show you a technique I've used recently to help develop an app containing not only a lot of view animations, but also had to support both Honeycomb and previous versions of the Android OS

What I discovered early on was that it gets ugly quickly trying to support multiple versions of Android in your app.  You end up with a lot of version checks throughout your apps Activity's.  Add to this the relatively verbose Animation code and things start to get out of hand.

In my case, I have various screen elements that can be in various states of display.  Specifically I have a video chooser that can be in 3 states (closed, open, full screen) and a playlist selection panel that can be shown and hidden.  On top of that I need to be able to hide the UI when a video is played and show it again when it's paused or finished.


I'm going to show you a nice clean way to deal with all those Animations across multiple OS versions in 3 steps.

First lets create a class that that will contain state information about our UI.  So I define a boolean for each View that can be shown or hidden in my UI.  Then I create a static enum defining my 3 positions for my video chooser view.

public class UIState {

    public static enum HeaderState {
     CLOSED,
     OPEN,
     FULL
    }
    
    private boolean mShowActionBar = true;
    private boolean mShowPlaylists = false;

    private boolean mShowHeader = true;
    private boolean mShowFilmStrip = false;
    private boolean mShowGrid = false;

Then create getters and setters for those data members.  I created a few additional methods to copy and compare UIState objects, as well as a few special setters for "configuring" my header, film strip and grid booleans in specific configurations.

    /**
     * @param mShowHeader
     *            the mShowHeader to set
     */
    public void setShowHeader() {
        mShowHeader = true;
        mShowFilmStrip = false;
        mShowGrid = false;
    }

    /**
     * @param mShowFilmStrip
     *            the mShowFilmStrip to set
     */
    public void setShowFilmStrip() {
        mShowHeader = true;
        mShowFilmStrip = true;
        mShowGrid = false;
    }

    /**
     * 
     * @param mShowGrid
     */
    public void setShowGrid() {
        mShowHeader = true;
        mShowFilmStrip = false;
        mShowGrid = true;
    }

Finally I create a method that will return the current state of the video chooser based on the configuration of header, film strip and grid.

    /**
     * Method that returns the current state of the header (CLOSED,OPEN,FULL)
     */
    public HeaderState getHeaderState() {
     if (showFilmStrip()) {
      return HeaderState.OPEN;
     }
     if (showGrid()) {
      return HeaderState.FULL;
     }
     if (!showFilmStrip() && !showGrid()) {
      return HeaderState.CLOSED;
     }
     // should only hit this if there is a bug in how we are setting our UI state objects
     return HeaderState.CLOSED;
    }

In part 2 I will show you how to create an Animation helper super class that we'll subclass for Honeycomb and Gingerbread and lower.  This is where we will define our individual animations for our views.

No comments:

Post a Comment