1、Camera 可以实现3D平移、旋转等特效:
2、它并不是以Galley视图所在坐标系,而是在其自身的坐标系
3、例如,其绕Y轴旋转,实际是在matrix 对应视图的左边旋转;平移也是同样。
package com.view; import android.content.Context; import android.graphics.Camera; import android.graphics.Matrix; import android.util.AttributeSet; import android.view.View; import android.view.animation.Transformation; import android.widget.Gallery; import android.widget.ImageView; /** * * */ public class GalleryFlow extends Gallery { private Camera mCamera = new Camera(); private int mMaxRotationAngle = 45; private int mMaxZoom = -120; private int mCoveflowCenter; private float mMaxDistance; private float mMaxZ = 100.0f; private float mMaxY = -40.0f; private float mMaxX = 60.0f; public GalleryFlow(Context context) { super(context); this.setStaticTransformationsEnabled(true); mMaxDistance = context.getResources().getDisplayMetrics().widthPixels >> 1; // Trace.Log("----------mMaxDistance------"+mMaxDistance); } public GalleryFlow(Context context, AttributeSet attrs) { super(context, attrs); this.setStaticTransformationsEnabled(true); mMaxDistance = context.getResources().getDisplayMetrics().widthPixels >> 1; // Trace.Log("----------mMaxDistance------"+mMaxDistance); } public GalleryFlow(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.setStaticTransformationsEnabled(true); mMaxDistance = context.getResources().getDisplayMetrics().widthPixels >> 1; // Trace.Log("----------mMaxDistance------"+mMaxDistance); } public int getMaxRotationAngle() { return mMaxRotationAngle; } public void setMaxRotationAngle(int maxRotationAngle) { mMaxRotationAngle = maxRotationAngle; } public int getMaxZoom() { return mMaxZoom; } public void setMaxZoom(int maxZoom) { mMaxZoom = maxZoom; } private int getCenterOfCoverflow() { return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft(); } private static int getCenterOfView(View view) { return view.getLeft() + view.getWidth() / 2; } protected boolean getChildStaticTransformation(View child, Transformation t) { final int childCenter = getCenterOfView(child); final int childWidth = child.getWidth(); int rotationAngle = 0; t.clear(); t.setTransformationType(Transformation.TYPE_MATRIX); if (childCenter == mCoveflowCenter) { transformImageBitmap((ImageView) child, t, 0); } else { rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle); if (Math.abs(rotationAngle) > mMaxRotationAngle * 4) { rotationAngle = 0; } transformImageBitmap((ImageView) child, t, rotationAngle); } return true; } private void transformImageBitmap(ImageView child, Transformation t, int rotationAngle) { mCamera.save(); final int MAX_MARGIN = 100;//设置最大间距 final Matrix imageMatrix = t.getMatrix(); final int imageWidth = child.getWidth(); float childCenter = getCenterOfView(child); float fromCenter = (mCoveflowCenter - childCenter); int margin = -(int) (MAX_MARGIN * fromCenter / imageWidth);//更具离中点的距离计算间距 if (rotationAngle < 0) { mCamera.translate(margin, 0, 0); mCamera.rotateY(-rotationAngle); } else if (rotationAngle > 0) { double pi = 3.14f * rotationAngle / 180f; int dz = (int) (imageWidth * Math.sin(pi));//需要向里(Z轴正方向)移动,以达到所需特效 int dx = (int) (imageWidth - imageWidth * Math.cos(pi)) + margin;//需要左移,保持间距 mCamera.translate(dx, 0, dz); mCamera.rotateY(-rotationAngle); } else { mCamera.rotateY(0); } mCamera.getMatrix(imageMatrix); mCamera.restore(); } protected void onSizeChanged(int w, int h, int oldw, int oldh) { mCoveflowCenter = getCenterOfCoverflow(); super.onSizeChanged(w, h, oldw, oldh); } }
另一个新的动画效果:
private void transformImageBitmap(View child, Transformation t, int rotationAngle) { mCamera.save(); final int MAX_MARGIN = 100; final Matrix imageMatrix = t.getMatrix(); final int width = child.getWidth(); final int height = child.getHeight(); float childCenter = getCenterOfView(child); int fromCenter = (int) (mCoveflowCenter - childCenter); int marginX = (MAX_MARGIN * fromCenter / width); int marginZ = (fromCenter / 2); int dx = marginX; int dz = Math.abs(marginZ); mCamera.translate(dx, 0, dz); mCamera.rotateY(rotationAngle); mCamera.getMatrix(imageMatrix);
//先将图片中心移动到原点,然后用Camera处理 ,最后还原;(默认图片左下角在原点)
//将图片中心移动到Y轴,使得Camera处理绕Y轴旋转时,即绕图片中心竖直方向旋转。(默认绕左边旋转)
// 将图片中心移动到原点,使得视点、原点、图片中心在同一直线。图片向里翻转时,上下端型变对称。(默认上端平直,下端倾斜)
imageMatrix.preTranslate(-(width / 2), -(height / 2)); imageMatrix.postTranslate((width / 2), (height / 2)); mCamera.restore(); }
第一个动画的优化:
private void transformImageBitmap(View child, Transformation t, int rotationAngle) { mCamera.save(); final int MAX_MARGIN = 0; final Matrix imageMatrix = t.getMatrix(); final int width = child.getWidth(); final int height = child.getHeight(); float childCenter = getCenterOfView(child); float fromCenter = (mCoveflowCenter - childCenter); int margin = -(int) (MAX_MARGIN * fromCenter / width); int marginZ = (int) (fromCenter *0.5); int dz = Math.abs(marginZ); mCamera.translate(margin, 0, dz); mCamera.rotateY(-rotationAngle); mCamera.getMatrix(imageMatrix); imageMatrix.preTranslate(-(width / 2), -(height / 2)); imageMatrix.postTranslate((width / 2), (height / 2)); mCamera.restore(); }