类似Chome的翻转效果

简单的demo,屏幕上下滑动翻转View,类似Android Chrome的效果

代码很简单,扩展一X轴旋转的动画RotateAnimationEX

package com.ray.animation;

import android.graphics.Camera;
import android.graphics.Matrix;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.Transformation;

public class RotateAnimationEX extends Animation {

	private float mFromDegress, mToDegress;
	private float mCenterX, mCenterY;
	private Camera mCamera;
	private OnFlipListener mFlipListener;
	private boolean onFilpped;
	public RotateAnimationEX(float fromDegrees, float toDegrees, int centerX, int centerY) {
		mFromDegress = fromDegrees;
		mToDegress = toDegrees;
		mCenterX = centerX;
		mCenterY = centerY;
		mCamera = new Camera();
		onFilpped = false;
	}
	
	public void setFlipListener(OnFlipListener listener) {
		mFlipListener = listener;
	}

	@Override
	protected void applyTransformation(float interpolatedTime, Transformation t) {
		mCamera.save();
		float rotateAngle = mFromDegress + (mToDegress - mFromDegress)*interpolatedTime;
		Log.d("Trace", "angel" + rotateAngle);
		if (mFlipListener != null) {
			if (rotateAngle >= 90 && rotateAngle <=180
			|| rotateAngle <=-90 && rotateAngle >= -180) {
				if (!onFilpped) {
					mFlipListener.onFlip();
					onFilpped = true;
				}
			} 
		}
		mCamera.rotateX(rotateAngle);
		Matrix m = t.getMatrix();
		mCamera.getMatrix(m);
		m.preTranslate(-mCenterX, -mCenterY);
		m.postTranslate(mCenterX, mCenterY);
		mCamera.restore();
	}
	
	public interface OnFlipListener {
		void onFlip();
	}
}
 

一测试的ViewGroup:

package com.ray.animation;

import com.ray.animation.RotateAnimationEX.OnFlipListener;

import android.content.Context;
import android.graphics.Camera;
import android.graphics.Color;
import android.graphics.Matrix;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Transformation;

public class TestViewGroup extends ViewGroup implements GestureDetector.OnGestureListener,
	OnFlipListener {

	public static final int MARGIN = 30;
	public static final int MAX_ROTATE_ANGLE = 90;
	private View mTestView;
	private RotateAnimationEX mRotaAnim;
	private GestureDetector mGestureDetector;
	private float rotateAngle = 0;
	private Camera mCamera;
	public TestViewGroup(Context context) {
		super(context);
		mTestView = new View(context);
		mTestView.setBackgroundColor(COLORS[0]);
		addView(mTestView);
		setStaticTransformationsEnabled(true);
		mGestureDetector = new GestureDetector(context,this);
		mCamera = new Camera();
	}
	
	@Override
	protected boolean getChildStaticTransformation(View child, Transformation t) {
		if (child == mTestView) {
			mCamera.save();
			Matrix m = t.getMatrix();
			mCamera.rotateX(rotateAngle);
			mCamera.getMatrix(m);
			m.preTranslate(-child.getWidth() / 2, -child.getHeight() / 2);
			m.postTranslate(child.getWidth() / 2, child.getHeight() / 2);
			mCamera.restore();
			return true;
		}
		return false;
	}



	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		mTestView.layout(l + MARGIN, t + MARGIN, r - MARGIN, b - MARGIN);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		
		boolean retValue = mGestureDetector.onTouchEvent(event);
		
		if (event.getAction() == MotionEvent.ACTION_UP) {
			mRotaAnim = new RotateAnimationEX(rotateAngle, 180*rotateAngle/Math.abs(rotateAngle),
					mTestView.getWidth()/2, mTestView.getHeight()/2);
			mRotaAnim.setFlipListener(this);
			mRotaAnim.setDuration(700);
			mRotaAnim.setFillAfter(true);
			mTestView.startAnimation(mRotaAnim);
			rotateAngle = 0;
		}
		return retValue;
	}

	@Override
	public boolean onDown(MotionEvent e) {
		if (mTestView != null)
			mTestView.clearAnimation();
		return true;
	}

	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		return false;
	}

	@Override
	public void onLongPress(MotionEvent e) {
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		rotateAngle = (e1.getY() - e2.getY()) / getHeight() * MAX_ROTATE_ANGLE;
		invalidate();
		return true;
	}

	@Override
	public void onShowPress(MotionEvent e) {	
	}

	@Override
	public boolean onSingleTapUp(MotionEvent e) {
		return false;
	}

	@Override
	public void onFlip() {
		mTestView.setBackgroundColor(COLORS[(++mCurrentColor) % COLORS.length]);
	}
	private static int mCurrentColor = 0;
	private static final int[] COLORS = new int[] {Color.BLUE, Color.RED};
}
 

使用代码:

package com.ray.demo;

import com.ray.animation.TestViewGroup;

import android.app.Activity;
import android.os.Bundle;

public class ChromeEggActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new TestViewGroup(this));
    }
}
 

猜你喜欢

转载自rayleung.iteye.com/blog/1680894