android视图360渡旋转效果
android视图360度旋转效果
1.重写Animation动画类,定义360度旋转
2.主方法:
首先定义一个layout,然后在该layout中定义两个layout,分别为旋转效果的正反面,
然后进行动画,在第一次的动画后放入监听事件,监听事件是第一次旋转90度,再触发监听事件执行Runnable触发第二次旋转。
视图配置文件,需要定义视图的正反面以及包含这两个正反面的视图:
1.重写Animation动画类,定义360度旋转
package com.test.animation; import android.view.animation.Animation; import android.view.animation.Transformation; import android.graphics.Camera; import android.graphics.Matrix; /** * An animation that rotates the view on the Y axis between two specified angles. * This animation also adds a translation on the Z axis (depth) to improve the effect. */ 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; /** * Creates a new 3D rotation on the Y axis. The rotation is defined by its * start angle and its end angle. Both angles are in degrees. The rotation * is performed around a center point on the 2D space, definied by a pair * of X and Y coordinates, called centerX and centerY. When the animation * starts, a translation on the Z axis (depth) is performed. The length * of the translation can be specified, as well as whether the translation * should be reversed in time. * * @param fromDegrees the start angle of the 3D rotation * @param toDegrees the end angle of the 3D rotation * @param centerX the X center of the 3D rotation * @param centerY the Y center of the 3D rotation * @param reverse true if the translation should be reversed, false otherwise */ 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 * 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); } }
2.主方法:
首先定义一个layout,然后在该layout中定义两个layout,分别为旋转效果的正反面,
然后进行动画,在第一次的动画后放入监听事件,监听事件是第一次旋转90度,再触发监听事件执行Runnable触发第二次旋转。
package com.test; import android.app.Activity; import android.os.Bundle; import android.view.Display; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.view.animation.AccelerateInterpolator; import android.view.animation.Animation; import android.view.animation.DecelerateInterpolator; import android.view.animation.Animation.AnimationListener; import android.widget.Button; import android.widget.RelativeLayout; import com.test.animation.Rotate3dAnimation; public class Main extends Activity { private Button testButton; private RelativeLayout animation_layout,animation_layout_temp; private ViewGroup mContainer; private boolean isAnswer; public static int screenWidth,screenHeight; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); testButton = (Button) findViewById(R.id.testButton); animation_layout = (RelativeLayout) findViewById(R.id.animation_layout); animation_layout_temp = (RelativeLayout) findViewById(R.id.animation_layout_temp); mContainer = (ViewGroup) findViewById(R.id.layout_main); mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE); Display display = getWindowManager().getDefaultDisplay(); screenWidth = display.getWidth(); screenHeight = display.getHeight(); testButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (isAnswer) { testButton.setText("Answer"); applyRotation(isAnswer, 0, 90); } else { testButton.setText("Question"); applyRotation(isAnswer, 0, 90); } } }); } private void applyRotation(boolean position,float start,float end) { final float centerX = mContainer.getWidth() / 2.0f; final float centerY = mContainer.getHeight() / 2.0f; final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY, screenWidth, true); rotation.setDuration(500); rotation.setFillAfter(true); rotation.setInterpolator(new AccelerateInterpolator()); rotation.setAnimationListener(new DisplayNextView(position)); mContainer.startAnimation(rotation); } private final class DisplayNextView implements AnimationListener { private final boolean mPosition; private DisplayNextView(boolean position) { mPosition = position; } @Override public void onAnimationEnd(Animation animation) { mContainer.post(new SwapViews(mPosition)); } @Override public void onAnimationRepeat(Animation animation) { // TODO Auto-generated method stub } @Override public void onAnimationStart(Animation animation) { // TODO Auto-generated method stub } } private final class SwapViews implements Runnable { private final boolean mPosition; public SwapViews(boolean position) { mPosition = position; } @Override public void run() { final float centerX = mContainer.getWidth() / 2.0f; final float centerY = mContainer.getHeight() / 2.0f; Rotate3dAnimation rotation; if (mPosition) { animation_layout_temp.setVisibility(View.VISIBLE); animation_layout.setVisibility(View.GONE); rotation = new Rotate3dAnimation(-90, 0, centerX, centerY, screenWidth-10.0f, false); } else { animation_layout_temp.setVisibility(View.GONE); animation_layout.setVisibility(View.VISIBLE); rotation = new Rotate3dAnimation(-90, 0, centerX, centerY, screenWidth-10.0f, false); } rotation.setDuration(500); rotation.setFillAfter(true); rotation.setInterpolator(new DecelerateInterpolator()); isAnswer = !mPosition; mContainer.startAnimation(rotation); } } }
视图配置文件,需要定义视图的正反面以及包含这两个正反面的视图:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:background="#FFFFFF" android:layout_height="fill_parent"> <RelativeLayout android:id="@+id/layout_main" android:layout_width="fill_parent" android:layout_height="300px" android:background="#AC4F3F"> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/animation_layout"> <LinearLayout android:layout_width="wrap_content" android:orientation="vertical" android:layout_centerInParent="true" android:layout_height="wrap_content" android:id="@+id/layout1"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello"/> </LinearLayout> </RelativeLayout> <RelativeLayout android:layout_width="fill_parent" android:layout_height="300px" android:id="@+id/animation_layout_temp" android:visibility="invisible"> <LinearLayout android:layout_width="wrap_content" android:orientation="vertical" android:layout_centerInParent="true" android:layout_height="wrap_content" android:id="@+id/layout1"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/app_name"/> </LinearLayout> </RelativeLayout> </RelativeLayout> <RelativeLayout android:layout_below="@id/layout_main" android:layout_width="fill_parent" android:layout_height="40px" android:background="#000"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Question" android:layout_centerInParent="true" android:id="@+id/testButton"></Button> </RelativeLayout> </RelativeLayout>