package com.test.photo; 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 { // 创建Camera对象 private Camera mCamera = new Camera(); // 最大旋转角度 private int mMaxRotateAngle = 60; // 最大缩放值 private int mMaxZoom = -120; private int mCoverflowCenter; public GalleryFlow(Context context) { super(context); setStaticTransformationsEnabled(true); } public GalleryFlow(Context context, AttributeSet attrs) { super(context, attrs); setStaticTransformationsEnabled(true); } public GalleryFlow(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setStaticTransformationsEnabled(true); } // 获得gallery展示图片的中心点 public int getCenterOfCoverflow() { return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 + getPaddingLeft(); } // 获得图片中心点 public int getCenterOfView(View view) { return view.getLeft() + view.getWidth() / 2; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { mCoverflowCenter = getCenterOfCoverflow(); super.onSizeChanged(w, h, oldw, oldh); } // 控制gallery中每个图片的旋转 @Override protected boolean getChildStaticTransformation(View child, Transformation t) { // 得到图片的重心点 final int childCenter = getCenterOfView(child); final int width = child.getLayoutParams().width; // 旋转角度 int rotationAngle = 0; //重置转换状态 t.clear(); //设置转换类型 t.setTransformationType(Transformation.TYPE_MATRIX); //如果图片位于中心位置不需要进行旋转 if (childCenter == mCoverflowCenter) { transformImageBitmap((ImageView) child, t, 0); } else { //根据图片在gallery中的位置来计算图片的旋转角度 rotationAngle = (int) ((float) (mCoverflowCenter - childCenter) / width * mMaxRotateAngle); //如果旋转角度绝对值大于最大旋转角度返回(-mMaxRotationAngle或mMaxRotationAngle;) if (Math.abs(rotationAngle) > mMaxRotateAngle) { rotationAngle = rotationAngle < 0 ? -mMaxRotateAngle : mMaxRotateAngle; } transformImageBitmap((ImageView) child, t, rotationAngle); } return true; } // 图片变形 private void transformImageBitmap(ImageView child, Transformation t, int rotateAngle) { // 保存图像变换的效果 mCamera.save(); final Matrix matrix = t.getMatrix(); // 图片高度 final int imageHeight = child.getLayoutParams().height; // 图片宽度 final int imageWidth = child.getLayoutParams().width; // 返回旋转角度的绝对值 final int rotation = Math.abs(rotateAngle); // 在Z轴上正向移动camera的视角,实际效果为放大图片。 // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。 mCamera.translate(0.0f, 0.0f, 100.0f); if (rotation < mMaxRotateAngle) { float zoom = (float) ((rotation * 1.5) + mMaxZoom); mCamera.translate(0.0f, 0.0f, zoom); child.setAlpha((int) (255 - rotation * 2.5)); } /// 在Y轴上旋转,对应图片竖向向里翻转。 // 如果在X轴上旋转,则对应图片横向向里翻转。 mCamera.rotateY(rotateAngle); mCamera.getMatrix(matrix); matrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2)); matrix.postTranslate((imageWidth / 2), (imageHeight / 2)); // 还原 mCamera.restore(); } }
package com.test.photo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Shader.TileMode; import android.graphics.drawable.BitmapDrawable; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; public class ImageAdapter extends BaseAdapter { private Context mContext; private int[] mImageIds; private ImageView[] mImages; public ImageAdapter(Context context, int[] imageIds) { this.mContext = context; this.mImageIds = imageIds; mImages = new ImageView[imageIds.length]; } @Override public int getCount() { return mImages.length; } @Override public Object getItem(int position) { return mImages[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { return mImages[position]; } // 生成带有倒影效果的图片 public boolean createReflectedImages() { // 原图片与倒影之间的距离 final int reflectionGap = 4; int index = 0; for (int imageId : mImageIds) { // 原图片 Bitmap originalImage = BitmapFactory.decodeResource( mContext.getResources(), imageId); int width = originalImage.getWidth(); int height = originalImage.getHeight(); // 创建矩阵对象 Matrix matrix = new Matrix(); matrix.preScale(1, -1); // 将矩阵应用到该原图之中,返回一个宽度不变,高度为原图1/2的倒影位图 Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height / 2, width, height / 2, matrix, false); // 创建一个宽度不变,高度为原图+倒影图高度的位图 Bitmap bitmapWithReflection = Bitmap.createBitmap(width, height + height / 2, Config.ARGB_8888); // 创建画布 Canvas canvas = new Canvas(bitmapWithReflection); // 绘制原图片 canvas.drawBitmap(originalImage, 0, 0, null); // 绘制原图片与倒影之间的距离 Paint defaultpaint = new Paint(); canvas.drawRect(0, height, width, height + reflectionGap, defaultpaint); // 绘制倒影图片 canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); Paint paint = new Paint(); paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); LinearGradient shader = new LinearGradient(0, height, 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70FFFFFF, 0x00FFFFFF, TileMode.MIRROR); // 着色器 用来绘制颜色 上色的 paint.setShader(shader); canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); // 创建一个ImageView用来显示已经画好的bitmapWithReflection ImageView imageView = new ImageView(mContext); BitmapDrawable bd = new BitmapDrawable(bitmapWithReflection); // 消除图片锯齿效果 bd.setAntiAlias(true); imageView.setImageDrawable(bd); // 设置图片的大小 imageView.setLayoutParams(new GalleryFlow.LayoutParams(160, 240)); mImages[index++] = imageView; } return true; } }
package com.test.photo; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { private GalleryFlow mGalleryFlow; private int[] imageIds = new int[] { R.drawable.nba_1, R.drawable.nba_2, R.drawable.nba_3, R.drawable.nba_4, R.drawable.nba_5, R.drawable.nba_6, R.drawable.nba_7, R.drawable.nba_8, R.drawable.nba_9, R.drawable.nba_10,}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); findViews(); initViews(); } private void findViews() { mGalleryFlow = (GalleryFlow) findViewById(R.id.gf); } private void initViews() { ImageAdapter adapter = new ImageAdapter(this, imageIds); // 生成带有倒影效果的图片 adapter.createReflectedImages(); mGalleryFlow.setAdapter(adapter); } }
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:background="@android:color/black" > <com.test.photo.GalleryFlow android:id="@+id/gf" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>