【最终效果】
1.相簿显示
在相簿显示中,我们不在使所有图像在同一水平线上了,对两侧的图片进行了一定过得角度旋转以及远小近大的处理
【MyMirrorGalley.java】
package com.example.jingxiang;
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 MyMirrorGallery extends Gallery {
private Camera mCamera = new Camera();
private int mMaxRotationAngle = 60;// y轴旋转角度
private int mMaxZoom = -380;// z轴平移距离
private int mCoveflowCenter;
private boolean mAlphaMode = true;
private boolean mCircleMode = false;
public int getMaxRotationAngle() { // 1
return mMaxRotationAngle;
}
// 构造函数
public MyMirrorGallery(Context context) {
super(context);
this.setStaticTransformationsEnabled(true);
}
public MyMirrorGallery(Context context, AttributeSet attrs) {
super(context, attrs);
this.setStaticTransformationsEnabled(true);
}
public MyMirrorGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.setStaticTransformationsEnabled(true);
}
public void setMaxRotationAngle(int mMaxRotationAngle) {
this.mMaxRotationAngle = mMaxRotationAngle;
}
public int getMaxZoon() { // 2
return mMaxRotationAngle;
}
public void setMaxZoon(int mMaxZoon) {
this.mMaxZoom = mMaxZoon;
}
public int getCenterOfCoverflow() {
return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
+ getPaddingLeft();
}
public void getAlphaMode(boolean mAlphaMode) {// 4
this.mAlphaMode = mAlphaMode;
}
public boolean setAlphaMode() {
return mAlphaMode;
}
public boolean getCircleMode() { // 5
return mCircleMode;
}
public void setCircleMode(boolean mCircleMode) {
this.mCircleMode = mCircleMode;
}
// 得到子对象的中线
private static int getCenterOfView(View view) {
return view.getLeft() + view.getWidth() / 2;
}
protected boolean getChildStaticTransformation(View view, Transformation t) {
final int mCenter = getCenterOfView(view);
final int mWidth = view.getWidth();
int rotationAngle = 0;
t.clear();
t.setTransformationType(Transformation.TYPE_MATRIX);
if (mWidth == mCoveflowCenter) {
/* 中间的图 */
transformationImageBitmap((ImageView) view, t, 0); // bitmap:位图
} else {
rotationAngle = (int) ((float) (mCoveflowCenter - mCenter) / mCenter)
* mMaxRotationAngle;
if (Math.abs(rotationAngle) > mMaxRotationAngle) {
rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
: mMaxRotationAngle;
}
/* 不是中间的图 */
transformationImageBitmap((ImageView) view, t, rotationAngle);
}
return true;
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCoveflowCenter = getCenterOfCoverflow();
super.onSizeChanged(w, h, oldw, oldh);
}
private void transformationImageBitmap(ImageView view, Transformation t,
int rotationAngle) {
// TODO Auto-generated method stub
mCamera.save();
final Matrix imageMatrix = t.getMatrix(); // matrix:矩阵
final int imageHeight = view.getLayoutParams().height;// param:参数
final int imageWidth = view.getLayoutParams().width;
final int rotation = Math.abs(rotationAngle); // rotation:旋转
mCamera.translate(0.0f, 0.0f, 100.0f);
if (rotationAngle <= mMaxRotationAngle) {
float zoomAmout = (float) (mMaxZoom + (rotation * 1.5));// zoom:距离
mCamera.translate(0.0f, 0.0f, zoomAmout);
if (mCircleMode) {
if (rotation < 40) {
mCamera.translate(0.0f, 155, 0.0f);
} else {
mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f);
}
}
mCamera.rotateY(rotationAngle);
mCamera.getMatrix(imageMatrix);
imageMatrix.preTranslate(-(imageWidth) / 2, -(imageHeight) / 2);
imageMatrix.postTranslate((imageWidth / 2), (imageHeight) / 2);
mCamera.restore(); // restory:备份 }
}
}
2.镜像效果
现在我们已经是正向显示有了立体效果,接下来,我们实现镜面的效果
【MyImage1.java】
package com.example.jingxiang; 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.util.AttributeSet; import android.widget.ImageView; public class MyImage1 extends ImageView { private boolean mReflectionMode = true; public MyImage1(Context context) { super(context); } public MyImage1(Context context, AttributeSet attrs) { super(context, attrs); // 取得原始图片的bitmap并重画 Bitmap originalImage = ((BitmapDrawable) this.getDrawable()) .getBitmap(); DoReflection(originalImage); } public MyImage1(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); Bitmap originalImage = ((BitmapDrawable) this.getDrawable()) .getBitmap(); DoReflection(originalImage); } //这个方法很重要,不然显示不了倒影 public void setImageResource(int resId) { Bitmap originalImage = BitmapFactory.decodeResource(getResources(), resId); DoReflection(originalImage); // super.setImageResource(resId); } private void DoReflection(Bitmap originalImage) { // TODO Auto-generated method stub final int reflectionGap = 4; int width = originalImage.getWidth(); int height = originalImage.getHeight(); Matrix matrix = new Matrix();// 矩阵 matrix.preScale(1, -1); // 创建一个新的bitmap,高度为原来的两倍,其中填充原图和倒影 Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, 0, width, (height / 4) * 3, matrix, false); Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height), Config.ARGB_8888);// config:配置 Canvas canvasRef = new Canvas(bitmapWithReflection);// canvas:帆布 // 先画原始图片 canvasRef.drawBitmap(originalImage, 0, 0, null); // 画间距——画矩形 drawRect (float left, float top, float right, float bottom, // Paint paint) Paint deafaultPaint = new Paint(); canvasRef.drawRect(0, height, width, height + reflectionGap, deafaultPaint);// rect:矩形 // 画翻转以后的图片drawBitmap (Bitmap bitmap, float left, float top, Paint // paint) canvasRef.drawBitmap(reflectionImage, 0, height + reflectionGap, null); Paint paint = new Paint(); // 画阴影LinearGradient (float x0, float y0, float x1, float y1, int // color0, int color1, Shader.TileMode tile) LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x80ffffff, 0x00ffffff, TileMode.CLAMP);// gradient:高度,坡度 paint.setShader(shader); paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); canvasRef.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); this.setImageBitmap(bitmapWithReflection); } }
3.显示图片
【MyImage.java】
package com.example.jingxiang;
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.util.AttributeSet;
import android.widget.ImageView;
public class MyImage1 extends ImageView {
private boolean mReflectionMode = true;
public MyImage1(Context context) {
super(context);
}
public MyImage1(Context context, AttributeSet attrs) {
super(context, attrs);
// 取得原始图片的bitmap并重画
Bitmap originalImage = ((BitmapDrawable) this.getDrawable())
.getBitmap();
DoReflection(originalImage);
}
public MyImage1(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
Bitmap originalImage = ((BitmapDrawable) this.getDrawable())
.getBitmap();
DoReflection(originalImage);
}
//这个方法很重要,不然显示不了倒影
public void setImageResource(int resId) {
Bitmap originalImage = BitmapFactory.decodeResource(getResources(),
resId);
DoReflection(originalImage);
// super.setImageResource(resId);
}
private void DoReflection(Bitmap originalImage) {
// TODO Auto-generated method stub
final int reflectionGap = 4;
int width = originalImage.getWidth();
int height = originalImage.getHeight();
Matrix matrix = new Matrix();// 矩阵
matrix.preScale(1, -1);
// 创建一个新的bitmap,高度为原来的两倍,其中填充原图和倒影
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, 0,
width, (height / 4) * 3, matrix, false);
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height), Config.ARGB_8888);// config:配置
Canvas canvasRef = new Canvas(bitmapWithReflection);// canvas:帆布
// 先画原始图片
canvasRef.drawBitmap(originalImage, 0, 0, null);
// 画间距——画矩形 drawRect (float left, float top, float right, float bottom,
// Paint paint)
Paint deafaultPaint = new Paint();
canvasRef.drawRect(0, height, width, height + reflectionGap,
deafaultPaint);// rect:矩形
// 画翻转以后的图片drawBitmap (Bitmap bitmap, float left, float top, Paint
// paint)
canvasRef.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
Paint paint = new Paint();
// 画阴影LinearGradient (float x0, float y0, float x1, float y1, int
// color0, int color1, Shader.TileMode tile)
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x80ffffff, 0x00ffffff, TileMode.CLAMP);// gradient:高度,坡度
paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
canvasRef.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
this.setImageBitmap(bitmapWithReflection);
}
}
4.适配器
【MyAdapter.java】
package com.example.jingxiang;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
public class MyAdapter extends BaseAdapter{
private Context mContext;
private Integer[] Imgid = { R.drawable.p1, R.drawable.p2, R.drawable.p3,
R.drawable.p4, R.drawable.p5 };
public MyAdapter(Context c) {
mContext = c;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return Imgid.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@SuppressWarnings("deprecation")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
MyImage1 image=new MyImage1(mContext);
image.setImageResource(Imgid[position]);
//设置图像大小
image.setLayoutParams(new MyMirrorGallery.LayoutParams(160,240));
//设置图像显示的模式
image.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
//设置抗锯齿
BitmapDrawable drawable=(BitmapDrawable)image.getDrawable();
drawable.setAntiAlias(true);//alias:别名
return image;
}
public float getScale(boolean focused, int offset) {
return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
}
}
5.布局文件
【activity_main.xml】
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.example.jingxiang.MyMirrorGallery
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/Mygallery"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>