先上一张效果图:
上代码,看了代码什么都明白
CoverFlow从Gallery继承过来
001 package com.coverflow;
002
003 import
Android.content.Context;
004 import
Android.graphics.Camera;
005 import
Android.graphics.Matrix;
006 import
Android.util.AttributeSet;
007 import
Android.view.View;
008 import
Android.view.animation.Transformation;
009 import
Android.widget.Gallery;
010 import
Android.widget.ImageView;
011
012 public class CoverFlow extends Gallery {
013
014 private Camera mCamera = new Camera();
015 private int mMaxRotationAngle = 50;
016 private int mMaxZoom = -380;
017 private int mCoveflowCenter;
018 private boolean mAlphaMode = true;
019 private boolean mCircleMode = false;
020
021 public CoverFlow(Context context) {
022 super(context);
023 this.setStaticTransformationsEnabled(true);
024 }
025
026 public CoverFlow(Context context, AttributeSet attrs) {
027 super(context, attrs);
028 this.setStaticTransformationsEnabled(true);
029 }
030
031 public CoverFlow(Context context, AttributeSet attrs, int defStyle) {
032 super(context, attrs, defStyle);
033 this.setStaticTransformationsEnabled(true);
034 }
035
036 public int getMaxRotationAngle() {
037 return mMaxRotationAngle;
038 }
039
040 public void setMaxRotationAngle(int maxRotationAngle) {
041 mMaxRotationAngle = maxRotationAngle;
042 }
043
044 public boolean getCircleMode() {
045 return mCircleMode;
046 }
047
048 public void setCircleMode(boolean isCircle) {
049 mCircleMode = isCircle;
050 }
051
052 public boolean getAlphaMode() {
053 return mAlphaMode;
054 }
055
056 public void setAlphaMode(boolean isAlpha) {
057 mAlphaMode = isAlpha;
058 }
059
060 public int getMaxZoom() {
061 return mMaxZoom;
062 }
063
064 public void setMaxZoom(int maxZoom) {
065 mMaxZoom = maxZoom;
066 }
067
068 private int getCenterOfCoverflow() {
069 return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
070 + getPaddingLeft();
071 }
072
073 private static int getCenterOfView(View view) {
074 return view.getLeft() + view.getWidth() / 2;
075 }
076
077 protected boolean getChildStaticTransformation(View child, Transformation t) {
078 final int childCenter = getCenterOfView(child);
079 final int childWidth = child.getWidth();
080 int rotationAngle = 0;
081 t.clear();
082 t.setTransformationType(Transformation.TYPE_MATRIX);
083 if (childCenter == mCoveflowCenter) {
084 transformImageBitmap((ImageView) child, t, 0);
085 } else {
086 rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
087 if (Math.abs(rotationAngle) > mMaxRotationAngle) {
088 rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
089 : mMaxRotationAngle;
090 }
091 transformImageBitmap((ImageView) child, t, rotationAngle);
092 }
093 return true;
094 }
095
096 /**
097 * 这就是所谓的在大小的布局时,这一观点已经发生了改变。如果 你只是添加到视图层次,有人叫你旧的观念 价值观为0。
098 *
099 * @param w
100 * Current width of this view.
101 * @param h
102 * Current height of this view.
103 * @param oldw
104 * Old width of this view.
105 * @param oldh
106 * Old height of this view.
107 */
108 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
109 mCoveflowCenter = getCenterOfCoverflow();
110 super.onSizeChanged(w, h, oldw, oldh);
111 }
112
113 /**
114 * 把图像位图的角度通过
115 *
116 * @param imageView
117 * ImageView the ImageView whose bitmap we want to rotate
118 * @param t
119 * transformation
120 * @param rotationAngle
121 * the Angle by which to rotate the Bitmap
122 */
123 private void transformImageBitmap(ImageView child, Transformation t,
124 int rotationAngle) {
125 mCamera.save();
126 final Matrix imageMatrix = t.getMatrix();
127 final int imageHeight = child.getLayoutParams().height;
128 final int imageWidth = child.getLayoutParams().width;
129 final int rotation = Math.abs(rotationAngle);
130 mCamera.translate(0.0f, 0.0f, 100.0f);
131
132 // 如视图的角度更少,放大
133 if (rotation <= mMaxRotationAngle) {
134 float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
135 mCamera.translate(0.0f, 0.0f, zoomAmount);
136 if (mCircleMode) {
137 if (rotation < 40)
138 mCamera.translate(0.0f, 155, 0.0f);
139 else
140 mCamera.translate(0.0f, (255 - rotation * 2.5f), 0.0f);
141 }
142 if (mAlphaMode) {
143 ((ImageView) (child)).setAlpha((int) (255 - rotation * 2.5));
144 }
145 }
146 mCamera.rotateY(rotationAngle);
147 mCamera.getMatrix(imageMatrix);
148 imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
149 imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
150 mCamera.restore();
151 }
152 }
这个就是CoverFlow类,说明几点:
1. 成员函数
mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等
mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度
mMaxZoom是图片在z轴平移的距离,视觉上看起来就是放大缩小的效果.
其他的变量都可以无视
也就是说把这个属性设成true的时候每次viewGroup(看Gallery的源码就可以看到它是从ViewGroup间接继承过来的)在重新画它的child的时候都会促发getChildStaticTransformation这个函数,所以我们只需要在这个函数里面去加上旋转和放大的操作就可以了
其他的getter和setter函数都可以无视
ImageAdapter适配器:
001 package com.coverflow;
002
003 import
Android.content.Context;
004 import
Android.graphics.Bitmap;
005 import
Android.graphics.BitmapFactory;
006 import
Android.graphics.Canvas;
007 import
Android.graphics.LinearGradient;
008 import
Android.graphics.Matrix;
009 import
Android.graphics.Paint;
010 import
Android.graphics.PorterDuffXfermode;
011 import
Android.graphics.Bitmap.Config;
012 import
Android.graphics.PorterDuff.Mode;
013 import
Android.graphics.Shader.TileMode;
014 import
Android.graphics.drawable.BitmapDrawable;
015 import
Android.view.View;
016 import
Android.view.ViewGroup;
017 import
Android.widget.BaseAdapter;
018 import
Android.widget.ImageView;
019
020 import com.gallery.R;
021
022 public class ImageAdapter extends BaseAdapter {
023 int mGalleryItemBackground;
024 private Context mContext;
025 private Integer[] mImageIds = {
026 R.drawable.a1,
027 R.drawable.a2,
028 R.drawable.a3,
029 R.drawable.a4,
030 R.drawable.a5 };
031
032 public ImageAdapter(Context c) {
033 mContext = c;
034 }
035
036 public int getCount() {
037 return mImageIds.length;
038 }
039
040 public Object getItem(int position) {
041 return position;
042 }
043
044 public long getItemId(int position) {
045 return position;
046 }
047
048 public View getView(int position, View convertView, ViewGroup parent) {
049
050 ImageView i = createReflectedImages(mContext,mImageIds[position]);
051
052 i.setLayoutParams(new CoverFlow.LayoutParams(120, 100));
053 i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
054
055 // 设置的抗锯齿
056 BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
057 drawable.setAntiAlias(true);
058 return i;
059 }
060
061 public float getScale(boolean focused, int offset) {
062 return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
063 }
064
065 public ImageView createReflectedImages(Context mContext,int imageId) {
066
067 Bitmap originalImage = BitmapFactory.decodeResource(mContext.getResources(), imageId);
068
069 final int reflectionGap = 4;
070
071 int width = originalImage.getWidth();
072 int height = originalImage.getHeight();
073
074 Matrix matrix = new Matrix();
075 matrix.preScale(1, -1);
076
077 Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
078 height / 2, width, height / 2, matrix, false);
079
080 Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
081 (height + height / 2), Config.ARGB_8888);
082
083 Canvas canvas = new Canvas(bitmapWithReflection);
084
085 canvas.drawBitmap(originalImage, 0, 0, null);
086
087 Paint deafaultPaint = new Paint();
088 canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint);
089
090 canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
091
092 Paint paint = new Paint();
093 LinearGradient shader = new LinearGradient(0, originalImage
094 .getHeight(), 0, bitmapWithReflection.getHeight()
095 + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.MIRROR);
096
097 paint.setShader(shader);
098
099 paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
100
101 canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
102 + reflectionGap, paint);
103
104 ImageView imageView = new ImageView(mContext);
105 imageView.setImageBitmap(bitmapWithReflection);
106
107 return imageView;
108 }
109
110 }
BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
drawable.setAntiAlias(true);
是保证图片绕Y旋转了以后不会出现锯齿.
下面是Activity:
01 package com.coverflow;
02
03 import
Android.app.Activity;
04 import
Android.graphics.Color;
05 import
Android.os.Bundle;
06
07 import com.gallery.R;
08
09 public class Hello
Android extends Activity {
10 /** Called when the activity is first created. */
11 @Override
12 public void onCreate(Bundle savedInstanceState) {
13 super.onCreate(savedInstanceState);
14
15 CoverFlow cf = new CoverFlow(this);
16 // cf.setBackgroundResource(R.drawable.shape);
17 cf.setBackgroundColor(Color.BLACK);
18 cf.setAdapter(new ImageAdapter(this));
19 ImageAdapter imageAdapter = new ImageAdapter(this);
20 cf.setAdapter(imageAdapter);
21 // cf.setAlphaMode(false);
22 // cf.setCircleMode(false);
23 cf.setSelection(2, true);
24 cf.setAnimationDuration(1000);
25 setContentView(cf);
26 }
27
28 }
摘自 迷途ф書童