Animation 2


<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ListView
        android:id="@android:id/list"
        android:persistentDrawingCache="animation|scrolling"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layoutAnimation="@anim/layout_bottom_to_top_slide" />

    <ImageView
        android:id="@+id/picture"
        android:scaleType="fitCenter"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="gone" />

</FrameLayout>

What is android FrameLayout and how is it used?

Search for: What is android FrameLayout and how is it used?

It doesn't have to be a list actiity. we will see it later

But there are some defaults laid out in android.R


simple_list_item_1
simple_list_item_2
simple_list_item_checked
simple_list_item_multiple_choice
simple_list_item_single_choice

More of these are at http://code.google.com/android/reference/android/R.layout.html


private static final 
  String[] PHOTOS_NAMES = new String[] {
        "Lyon",
        "Livermore",
        "Tahoe Pier",
        "Lake Tahoe",
        "Grand Canyon",
        "Bodie"
  };

//Set the activity layout first
setContentView(R.layout.animations_main_screen);

//get the list view
mPhotoListView = (ListView) findViewById(android.R.id.list);

//get an adapter
ArrayAdapter<String> adapter = 
   new ArrayAdapter<String>(this
           ,android.R.layout.simple_list_item_1
           ,PHOTOS_NAMES);

//Notice how it uses a predefined view
//for the list item

//Attach the adapter to the list
mPhotosListView.setAdapter(adapter);

setOnItemClickListener

You will have to implement OnItemClickListener


public void onItemClick(AdapterView parent
       , View v
       , int position
       , long id) 
{
      // Pre-load the image then start the animation
      mImageView.setImageResource(PHOTOS_RESOURCES[position]);
      applyRotation(position, 0, 90);
}

position: The position of the view in the adapter

id: The row id of the item that was clicked

How is postion different from id in onItemClick Method?

Search for: How is postion different from id in onItemClick Method?


mPhotosListView.setOnItemClickListener(this);

Where "this" should point to a class that implements the AdapterView.OnItemClickListener interface

Here is the story on FrameLayout

FrameLayout is designed to block out an area on the screen to display a single item. You can add multiple children to a FrameLayout, but all children are pegged to the top left of the screen. Children are drawn in a stack, with the most recently added child on top. The size of the frame layout is the size of its largest child (plus padding), visible or not (if the FrameLayout's parent permits). Views that are GONE are used for sizing only if setConsiderGoneChildrenWhenMeasuring() is set to true.


private void applyRotation(int position, float start, float end) 
{
        // Find the center of the container
        final float centerX = mContainer.getWidth() / 2.0f;
        final float centerY = mContainer.getHeight() / 2.0f;

        // Create a new 3D rotation with the supplied parameter
        // The animation listener is used to trigger the next animation
        final Rotate3dAnimation rotation =
                new Rotate3dAnimation(start, end, centerX, 
                     centerY, 310.0f, true);
        rotation.setDuration(500);
        rotation.setFillAfter(true);
        rotation.setInterpolator(new AccelerateInterpolator());
        rotation.setAnimationListener(new DisplayNextView(position));

        mContainer.startAnimation(rotation);
}

whats up with android.graphics.Camera

Search for: whats up with android.graphics.Camera

what are yaw, roll, and pitch in animation?

Search for: what are yaw, roll, and pitch in animation?

graphics matrix translation

Search for: graphics matrix translation

Read this discussion on rotation

sample code for animation


public class Rotate3dAnimation extends Animation 
{
    public Rotate3dAnimation(....){}

    @Override
    public void initialize(int width, int height, 
                  int parentWidth, int parentHeight) 
   {
        super.initialize(width, height, parentWidth, parentHeight);
      ....your stuff
    }

    @Override
    protected void applyTransformation(float interpolatedTime
                                      ,Transformation t) 
    {
    }
    
    protected void applyTransformationNew(float interpolatedTime
                                        ,Transformation t) 
    {
        final Matrix matrix = t.getMatrix();
      //Change this matrix in some manner
    }
}

view.startAnimation(YourAnimationObject)

public class TranslateAnimation extends Animation {
    private int mFromXType = ABSOLUTE;
    private int mToXType = ABSOLUTE;

    private int mFromYType = ABSOLUTE;
    private int mToYType = ABSOLUTE;

    private float mFromXValue = 0.0f;
    private float mToXValue = 0.0f;

    private float mFromYValue = 0.0f;
    private float mToYValue = 0.0f;

    private float mFromXDelta;
    private float mToXDelta;
    private float mFromYDelta;
    private float mToYDelta;

    public TranslateAnimation(float fromXDelta, float toXDelta, 
                           float fromYDelta, float toYDelta) {
        mFromXValue = fromXDelta;
        mToXValue = toXDelta;
        mFromYValue = fromYDelta;
        mToYValue = toYDelta;

        mFromXType = ABSOLUTE;
        mToXType = ABSOLUTE;
        mFromYType = ABSOLUTE;
        mToYType = ABSOLUTE;
    }

     */
    public TranslateAnimation(int fromXType, float fromXValue, 
        int toXType, float toXValue,
         int fromYType, float fromYValue, int toYType, float toYValue) 
{
        mFromXValue = fromXValue;
        mToXValue = toXValue;
        mFromYValue = fromYValue;
        mToYValue = toYValue;

        mFromXType = fromXType;
        mToXType = toXType;
        mFromYType = fromYType;
        mToYType = toYType;
    }


    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t)
   {
        float dx = mFromXDelta;
        float dy = mFromYDelta;
        if (mFromXDelta != mToXDelta) {
            dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
        }
        if (mFromYDelta != mToYDelta) {
            dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
        }

        t.getMatrix().setTranslate(dx, dy);
    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight)
   {
        super.initialize(width, height, parentWidth, parentHeight);
        mFromXDelta = resolveSize(mFromXType, mFromXValue, width, parentWidth);
        mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
        mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
        mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight);
    }
}

private void applyRotation(int position, float start, float end) {
        // Find the center of the container
        final float centerX = mContainer.getWidth() / 2.0f;
        final float centerY = mContainer.getHeight() / 2.0f;

        // Create a new 3D rotation with the supplied parameter
        // The animation listener is used to trigger the next animation
        final Rotate3dAnimation rotation =
                new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
        rotation.setDuration(500);
        rotation.setFillAfter(true);
        rotation.setInterpolator(new AccelerateInterpolator());
        rotation.setAnimationListener(new DisplayNextView(position));

        mContainer.startAnimation(rotation);
    }

where "mContainer" is the view group pointing to a FrameLayout

You start the animation with startAnimation and then you register a callback when the animation finishes.


private final class DisplayNextView 
implements Animation.AnimationListener 
{
        private final int mPosition;
        private DisplayNextView(int position) {
            mPosition = position;
        }

        public void onAnimationStart(Animation animation) {}

        public void onAnimationEnd(Animation animation) 
        {
           mContainer.post(new SwapViews(mPosition));
        }

        public void onAnimationRepeat(Animation animation) {
        }
    }

private final class SwapViews implements Runnable {
        private final int mPosition;

        public SwapViews(int position) {
            mPosition = position;
        }

        public void run() {
            final float centerX = mContainer.getWidth() / 2.0f;
            final float centerY = mContainer.getHeight() / 2.0f;
            Rotate3dAnimation rotation;
            
            if (mPosition > -1) {
                mPhotosList.setVisibility(View.GONE);
                mImageView.setVisibility(View.VISIBLE);
                mImageView.requestFocus();

                rotation = 
                new Rotate3dAnimation(90, 180, centerX, centerY, 
                                                310.0f, false);
            } else {
                mImageView.setVisibility(View.GONE);
                mPhotosList.setVisibility(View.VISIBLE);
                mPhotosList.requestFocus();

                rotation = new Rotate3dAnimation(90, 0, centerX, 
                                 centerY, 310.0f, false);
            }

            rotation.setDuration(500);
            rotation.setFillAfter(true);
            rotation.setInterpolator(new DecelerateInterpolator());

            mContainer.startAnimation(rotation);
        }
    }

android post runnable

Search for: android post runnable

post runs the action on the UI theread


protected void applyTransformationOld(float interpolatedTime, 
               Transformation t) 
{
        final float fromDegrees = mFromDegrees;
        float degrees = fromDegrees + 
              ((mToDegrees - fromDegrees) * interpolatedTime);

        final float centerX = mCenterX;
        final float centerY = mCenterY;
        final Camera camera = mCamera;

        final Matrix matrix = t.getMatrix();

        camera.save();
        if (mReverse) {
            camera.translate(0.0f, 0.0f, 
                   mDepthZ * interpolatedTime);
        } else {
            camera.translate(0.0f, 0.0f, 
                mDepthZ * (1.0f - interpolatedTime));
        }
        camera.rotateY(degrees);
        camera.getMatrix(matrix);
        camera.restore();

        matrix.preTranslate(-centerX, -centerY);
        matrix.postTranslate(centerX, centerY);
}

Camera
Matrix

Animation
and its derived classes

// Prepare the ImageView
        mImageView.setClickable(true);
        mImageView.setFocusable(true);
        mImageView.setOnClickListener(this);

mContainer.
     setPersistentDrawingCache(
            ViewGroup.PERSISTENT_ANIMATION_CACHE);

what is setPersistentDrawingCache

Search for: what is setPersistentDrawingCache