Saturday, March 16, 2013

How to rotate ListView Items in Android

This one is really the sexiest animations i have implemented.I needed to rotate the items of the list view on the x-axis 360 degrees.Honestly speaking i search over the net and found a sample which was doing the animation but that was using LayoutAnimationController which rotates the items one by one they are added to the listView.But I had to rotate the items simultaneously.So i used of the code which i used for another ListView Animation that i ll post here soon.

                  Have a look at code here which is self explanatory.


Here is the Layout file containing ListView : activity_main.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

    <Button
        android:id="@+id/refresh"
        style="?android:attr/buttonStyleSmall"
        android:layout_width="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_height="wrap_content"
        android:text="refresh" />

<ListView
    android:id = "@+id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  
    />
</LinearLayout>
------------------------------------------------------------------------------------------------------------------------------------
Here is the Activity Class having logic for rotation :
package com.example.rotatelistitems;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.animation.AccelerateInterpolator;

import android.view.animation.Animation;

import android.view.animation.AnimationSet;

import android.view.animation.LayoutAnimationController;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.ListView;

public class MainActivity extends Activity implements Runnable {

    String[] items={"India", "America", "Pakistan", "Afganistan", "Srilanka",

               "Paris", "London", "Australia", "Switzerland", "China",

               "Japan", "Malasiya", "Singapore", "Thailand", "Italy",

               "Russia", "Ukraine", "Germany", "Canada"};

   

        Button refresh ;

        /** Called when the activity is first created. */

        @Override

        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_main);

            final ListView flightlist = (ListView)findViewById(R.id.list);

            refresh                =    ( Button )findViewById(R.id.refresh);

            flightlist.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1,items));

           

           

            refresh.setOnClickListener(new OnClickListener() {

               

                @Override

                public void onClick(View v) {

                   

                    flightlist.post(MainActivity.this);

                   

                   

                }

            });

                                }

       

     

        private Rotate3dAnimation applyRotation(int position, float start, float end) {

            // Find the center of the container ,here i have hardcoded the values

            final float centerX = 0.0f;//view.getWidth()/2.0f;

            final float centerY = 50.0f;//view.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 , 0.0f , true );

            rotation.setDuration(500);

            rotation.setFillAfter(true);

            rotation.setRepeatCount(3);

            rotation.setInterpolator(new AccelerateInterpolator());

            rotation.setAnimationListener(new DisplayNextView(position));

            return rotation;

        }

     

        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) {

            }

            public void onAnimationRepeat(Animation animation) {

            }

        }

        @Override

        public void run() {

            ListView lv = (ListView) findViewById(R.id.list);

            // here animations start

            int first = lv.getFirstVisiblePosition();

            int last = lv.getLastVisiblePosition();

            for (int k = 0; k < last - first + 1; k++) {

                    View child = lv.getChildAt(k);

                 //   int pos = lv.getPositionForView(child);

                    child.startAnimation(applyRotation(0,0,360));

                

                

            }

           

        }

    }

This one is the custom Animation class for rotating ChildViews of a list
package com.example.rotatelistitems;

import android.graphics.Camera;

import android.graphics.Matrix;

import android.view.animation.Animation;

import android.view.animation.Transformation;

public class Rotate3dAnimation extends Animation {

    private final float mFromDegrees;

    private final float mToDegrees;

    private final float mCenterX;

    private final float mCenterY;

    private final float mDepthZ;

    private final boolean mReverse;

    private Camera mCamera;

   

    public Rotate3dAnimation(float fromDegrees, float toDegrees,

            float centerX, float centerY, float depthZ, boolean reverse) {

        mFromDegrees = fromDegrees;

        mToDegrees = toDegrees;

        mCenterX = centerX;

        mCenterY = centerY;

        mDepthZ = depthZ;

        mReverse = reverse;

    }

    @Override

    public void initialize(int width, int height, int parentWidth, int parentHeight) {

        super.initialize(width, height, parentWidth, parentHeight);

        mCamera = new Camera();

    }

    @Override

    protected void applyTransformation( 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 * ( 1.0f - interpolatedTime ) );

        } else {

            camera.translate( 0.0f , 0.0f , mDepthZ * ( 1.0f - interpolatedTime ) );

        }

        camera.rotateX(degrees);

        camera.getMatrix(matrix);

        camera.restore();

        matrix.preTranslate(-centerX, -centerY);

        matrix.postTranslate(centerX, centerY);

    }

}

Change the values and enjoy various behaviour of ListView Animation. Please do comment if you like my post :)

1 comment:

  1. Hi Anshul
    I am Vishal Chauhan
    I am using your code but it gives me error -

    FATAL EXCEPTION: main
    AndroidRuntime(22170): java.lang.RuntimeException: Unable to start activity
    ....
    ....
    Caused by: java.lang.NullPointerException



    i have tried lot to solve it but couldn't work
    can you help me?

    ReplyDelete