
贴上代码:
1.扩展Gallery:
001 | public class GalleryFlow extends Gallery { |
002 | private Camera mCamera = new Camera(); |
003 | private int mMaxRotationAngle = 60; |
004 | private int mMaxZoom = -300; |
005 | private int mCoveflowCenter; |
006 | public GalleryFlow(Context context) { |
009 | this.setStaticTransformationsEnabled(true); |
011 | public GalleryFlow(Context context, AttributeSet attrs) { |
012 | super(context, attrs); |
013 | this.setStaticTransformationsEnabled(true); |
015 | public GalleryFlow(Context context, AttributeSet attrs, int defStyle) { |
016 | super(context, attrs, defStyle); |
017 | this.setStaticTransformationsEnabled(true); |
019 | public int getMaxRotationAngle() { |
020 | return mMaxRotationAngle; |
022 | public void setMaxRotationAngle(int maxRotationAngle) { |
023 | mMaxRotationAngle = maxRotationAngle; |
025 | public int getMaxZoom() { |
028 | public void setMaxZoom(int maxZoom) { |
031 | private int getCenterOfCoverflow() { |
032 | return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2 |
035 | private static int getCenterOfView(View view) { |
036 | System.out.println("view left :"+view.getLeft()); |
037 | System.out.println("view width :"+view.getWidth()); |
038 | return view.getLeft() + view.getWidth() / 2; |
043 | protected boolean getChildStaticTransformation(View child, Transformation t) { |
045 | final int childCenter = getCenterOfView(child); |
046 | System.out.println("childCenter:"+childCenter); |
047 | final int childWidth = child.getWidth(); |
049 | int rotationAngle = 0; |
053 | t.setTransformationType(Transformation.TYPE_MATRIX); |
055 | if (childCenter == mCoveflowCenter) { |
056 | transformImageBitmap((ImageView) child, t, 0); |
059 | rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle); |
060 | System.out.println("rotationAngle:" +rotationAngle); |
062 | if (Math.abs(rotationAngle) > mMaxRotationAngle) { |
063 | rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle : mMaxRotationAngle; |
065 | transformImageBitmap((ImageView) child, t, rotationAngle); |
069 | protected void onSizeChanged(int w, int h, int oldw, int oldh) { |
070 | mCoveflowCenter = getCenterOfCoverflow(); |
071 | super.onSizeChanged(w, h, oldw, oldh); |
073 | private void transformImageBitmap(ImageView child, Transformation t, |
077 | final Matrix imageMatrix = t.getMatrix(); |
079 | final int imageHeight = child.getLayoutParams().height; |
081 | final int imageWidth = child.getLayoutParams().width; |
084 | final int rotation = Math.abs(rotationAngle); |
088 | mCamera.translate(0.0f, 0.0f, 100.0f); |
090 | if (rotation < mMaxRotationAngle) { |
091 | float zoomAmount = (float) (mMaxZoom + (rotation * 1.5)); |
092 | mCamera.translate(0.0f, 0.0f, zoomAmount); |
096 | mCamera.rotateY(rotationAngle); |
097 | mCamera.getMatrix(imageMatrix); |
098 | imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2)); |
099 | imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2)); |
104 | 2.填充图片容器(BaseAdapter): |
105 | public class ImageAdapter extends BaseAdapter { |
106 | int mGalleryItemBackground; |
107 | private Context mContext; |
108 | private Integer[] mImageIds; |
109 | private ImageView[] mImages; |
111 | public ImageAdapter(Context c, Integer[] ImageIds) { |
113 | mImageIds = ImageIds; |
114 | mImages = new ImageView[mImageIds.length]; |
120 | public boolean createReflectedImages() { |
122 | final int reflectionGap = 4; |
124 | for (int imageId : mImageIds) { |
126 | Bitmap originalImage = BitmapFactory.decodeResource(mContext.getResources(), imageId); |
127 | int width = originalImage.getWidth(); |
128 | int height = originalImage.getHeight(); |
130 | Matrix matrix = new Matrix(); |
136 | matrix.preScale(1, -1); |
139 | Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, |
140 | height/2, width, height/2, matrix, false); |
143 | Bitmap bitmapWithReflection = Bitmap.createBitmap(width, |
144 | (height + height / 2), Config.ARGB_8888); |
147 | Canvas canvas = new Canvas(bitmapWithReflection); |
148 | canvas.drawBitmap(originalImage, 0, 0, null); |
150 | Paint deafaultPaint = new Paint(); |
151 | deafaultPaint.setAntiAlias(false); |
153 | canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); |
154 | Paint paint = new Paint(); |
155 | paint.setAntiAlias(false); |
162 | * 这里设置为镜像Gradient是基于Shader类,所以我们通过Paint的setShader方法来设置这个渐变 |
164 | LinearGradient shader = new LinearGradient(0,originalImage.getHeight(), 0, |
165 | bitmapWithReflection.getHeight() + reflectionGap,0x70ffffff, 0x00ffffff, TileMode.MIRROR); |
167 | paint.setShader(shader); |
168 | paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN)); |
170 | canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()+ reflectionGap, paint); |
173 | ImageView imageView = new ImageView(mContext); |
174 | imageView.setImageBitmap(bitmapWithReflection); |
176 | imageView.setLayoutParams(new GalleryFlow.LayoutParams(300, 400)); |
178 | mImages[index++] = imageView; |
182 | @SuppressWarnings("unused") |
183 | private Resources getResources() { |
186 | public int getCount() { |
187 | return mImageIds.length; |
189 | public Object getItem(int position) { |
192 | public long getItemId(int position) { |
195 | public View getView(int position, View convertView, ViewGroup parent) { |
196 | return mImages[position]; |
198 | public float getScale(boolean focused, int offset) { |
199 | return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset))); |
204 | public class Gallery3DActivity extends Activity { |
205 | public void onCreate(Bundle savedInstanceState) { |
206 | super.onCreate(savedInstanceState); |
209 | setContentView(R.layout.layout_gallery); |
211 | Integer[] images = { R.drawable.img0001, R.drawable.img0030, |
212 | R.drawable.img0100, R.drawable.img0130, R.drawable.img0200, |
213 | R.drawable.img0230, R.drawable.img0330,R.drawable.img0354 }; |
215 | ImageAdapter adapter = new ImageAdapter(this, images); |
216 | adapter.createReflectedImages(); |
217 | GalleryFlow galleryFlow = (GalleryFlow) this.findViewById(R.id.Gallery01); |
218 | galleryFlow.setFadingEdgeLength(0); |
219 | galleryFlow.setSpacing(-100); |
220 | galleryFlow.setAdapter(adapter); |
222 | galleryFlow.setOnItemClickListener(new OnItemClickListener() { |
223 | public void onItemClick(AdapterView parent, View view, |
224 | int position, long id) { |
225 | Toast.makeText(getApplicationContext(), String.valueOf(position), Toast.LENGTH_SHORT).show(); |
229 | galleryFlow.setSelection(4); |
以上实现代码里面我都做了注释相信大家完全可以看懂。稍微解释下,在BaseAdapter中主要做了图片的倒影效果以及创建了对原始图片和倒影的显示区域。GalleryFlow中主要做了对图片的旋转和缩放操作,根据图片的屏幕中的位置对其进行旋转缩放操作