Home | History | Annotate | Download | only in animation
      1 package com.example.android.apis.animation;
      2 
      3 import com.example.android.apis.R;
      4 
      5 import android.app.Activity;
      6 import android.os.Bundle;
      7 import android.widget.ListView;
      8 import android.widget.ArrayAdapter;
      9 import android.widget.AdapterView;
     10 import android.widget.ImageView;
     11 import android.view.View;
     12 import android.view.ViewGroup;
     13 import android.view.animation.Animation;
     14 import android.view.animation.AccelerateInterpolator;
     15 import android.view.animation.DecelerateInterpolator;
     16 
     17 /**
     18  * This sample application shows how to use layout animation and various
     19  * transformations on views. The result is a 3D transition between a
     20  * ListView and an ImageView. When the user clicks the list, it flips to
     21  * show the picture. When the user clicks the picture, it flips to show the
     22  * list. The animation is made of two smaller animations: the first half
     23  * rotates the list by 90 degrees on the Y axis and the second half rotates
     24  * the picture by 90 degrees on the Y axis. When the first half finishes, the
     25  * list is made invisible and the picture is set visible.
     26  */
     27 public class Transition3d extends Activity implements
     28         AdapterView.OnItemClickListener, View.OnClickListener {
     29     private ListView mPhotosList;
     30     private ViewGroup mContainer;
     31     private ImageView mImageView;
     32 
     33     // Names of the photos we show in the list
     34     private static final String[] PHOTOS_NAMES = new String[] {
     35             "Lyon",
     36             "Livermore",
     37             "Tahoe Pier",
     38             "Lake Tahoe",
     39             "Grand Canyon",
     40             "Bodie"
     41     };
     42 
     43     // Resource identifiers for the photos we want to display
     44     private static final int[] PHOTOS_RESOURCES = new int[] {
     45             R.drawable.photo1,
     46             R.drawable.photo2,
     47             R.drawable.photo3,
     48             R.drawable.photo4,
     49             R.drawable.photo5,
     50             R.drawable.photo6
     51     };
     52 
     53     @Override
     54     protected void onCreate(Bundle savedInstanceState) {
     55         super.onCreate(savedInstanceState);
     56 
     57         setContentView(R.layout.animations_main_screen);
     58 
     59         mPhotosList = (ListView) findViewById(android.R.id.list);
     60         mImageView = (ImageView) findViewById(R.id.picture);
     61         mContainer = (ViewGroup) findViewById(R.id.container);
     62 
     63         // Prepare the ListView
     64         final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
     65                 android.R.layout.simple_list_item_1, PHOTOS_NAMES);
     66 
     67         mPhotosList.setAdapter(adapter);
     68         mPhotosList.setOnItemClickListener(this);
     69 
     70         // Prepare the ImageView
     71         mImageView.setClickable(true);
     72         mImageView.setFocusable(true);
     73         mImageView.setOnClickListener(this);
     74 
     75         // Since we are caching large views, we want to keep their cache
     76         // between each animation
     77         mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);
     78     }
     79 
     80     /**
     81      * Setup a new 3D rotation on the container view.
     82      *
     83      * @param position the item that was clicked to show a picture, or -1 to show the list
     84      * @param start the start angle at which the rotation must begin
     85      * @param end the end angle of the rotation
     86      */
     87     private void applyRotation(int position, float start, float end) {
     88         // Find the center of the container
     89         final float centerX = mContainer.getWidth() / 2.0f;
     90         final float centerY = mContainer.getHeight() / 2.0f;
     91 
     92         // Create a new 3D rotation with the supplied parameter
     93         // The animation listener is used to trigger the next animation
     94         final Rotate3dAnimation rotation =
     95                 new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
     96         rotation.setDuration(500);
     97         rotation.setFillAfter(true);
     98         rotation.setInterpolator(new AccelerateInterpolator());
     99         rotation.setAnimationListener(new DisplayNextView(position));
    100 
    101         mContainer.startAnimation(rotation);
    102     }
    103 
    104     public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
    105         // Pre-load the image then start the animation
    106         mImageView.setImageResource(PHOTOS_RESOURCES[position]);
    107         applyRotation(position, 0, 90);
    108     }
    109 
    110     public void onClick(View v) {
    111         applyRotation(-1, 180, 90);
    112     }
    113 
    114     /**
    115      * This class listens for the end of the first half of the animation.
    116      * It then posts a new action that effectively swaps the views when the container
    117      * is rotated 90 degrees and thus invisible.
    118      */
    119     private final class DisplayNextView implements Animation.AnimationListener {
    120         private final int mPosition;
    121 
    122         private DisplayNextView(int position) {
    123             mPosition = position;
    124         }
    125 
    126         public void onAnimationStart(Animation animation) {
    127         }
    128 
    129         public void onAnimationEnd(Animation animation) {
    130             mContainer.post(new SwapViews(mPosition));
    131         }
    132 
    133         public void onAnimationRepeat(Animation animation) {
    134         }
    135     }
    136 
    137     /**
    138      * This class is responsible for swapping the views and start the second
    139      * half of the animation.
    140      */
    141     private final class SwapViews implements Runnable {
    142         private final int mPosition;
    143 
    144         public SwapViews(int position) {
    145             mPosition = position;
    146         }
    147 
    148         public void run() {
    149             final float centerX = mContainer.getWidth() / 2.0f;
    150             final float centerY = mContainer.getHeight() / 2.0f;
    151             Rotate3dAnimation rotation;
    152 
    153             if (mPosition > -1) {
    154                 mPhotosList.setVisibility(View.GONE);
    155                 mImageView.setVisibility(View.VISIBLE);
    156                 mImageView.requestFocus();
    157 
    158                 rotation = new Rotate3dAnimation(90, 180, centerX, centerY, 310.0f, false);
    159             } else {
    160                 mImageView.setVisibility(View.GONE);
    161                 mPhotosList.setVisibility(View.VISIBLE);
    162                 mPhotosList.requestFocus();
    163 
    164                 rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f, false);
    165             }
    166 
    167             rotation.setDuration(500);
    168             rotation.setFillAfter(true);
    169             rotation.setInterpolator(new DecelerateInterpolator());
    170 
    171             mContainer.startAnimation(rotation);
    172         }
    173     }
    174 
    175 }
    176