我们专业课有Android的学习,最后老师让做一个简单的Android应用程序.我在网上找些资料,加上自己改造一下做了一个3D相册.
程序仿照Android的相册功能,调用Gallery类对相片进行浏览.实现3D效果.其中不足的地方就是里面的图片都是写死的.这一点可以改进.程序中使用Png格式图片,注意图片不要太大,500*500一下最好.
首先:
GalleryFlow.java 类 用来实现图片放映查看效果.
1: package com.android.CustomGallery;<!--CRLF-->
2:
<!--CRLF-->
3: import android.content.Context;<!--CRLF-->
4: import android.graphics.Camera;<!--CRLF-->
5: import android.graphics.Matrix;<!--CRLF-->
6: import android.util.AttributeSet;<!--CRLF-->
7: import android.util.Log;<!--CRLF-->
8: import android.view.View;<!--CRLF-->
9: import android.view.animation.Transformation;<!--CRLF-->
10: import android.widget.Gallery;<!--CRLF-->
11: import android.widget.ImageView;<!--CRLF-->
12:
<!--CRLF-->
13: public class GalleryFlow extends Gallery {<!--CRLF-->
14:
<!--CRLF-->
15: /**<!--CRLF-->
16: * Graphics Camera used for transforming the matrix of ImageViews<!--CRLF-->
17: */<!--CRLF-->
18: private Camera mCamera = new Camera();<!--CRLF-->
19:
<!--CRLF-->
20: /**<!--CRLF-->
21: * The maximum angle the Child ImageView will be rotated by<!--CRLF-->
22: */<!--CRLF-->
23: private int mMaxRotationAngle = 60;<!--CRLF-->
24:
<!--CRLF-->
25: /**<!--CRLF-->
26: * The maximum zoom on the centre Child<!--CRLF-->
27: */<!--CRLF-->
28: private int mMaxZoom = -120;<!--CRLF-->
29:
<!--CRLF-->
30: /**<!--CRLF-->
31: * The Centre of the Coverflow<!--CRLF-->
32: */<!--CRLF-->
33: private int mCoveflowCenter;<!--CRLF-->
34:
<!--CRLF-->
35: public GalleryFlow(Context context) {<!--CRLF-->
36: super(context);<!--CRLF-->
37: this.setStaticTransformationsEnabled(true);<!--CRLF-->
38: }
<!--CRLF-->
39:
<!--CRLF-->
40: public GalleryFlow(Context context, AttributeSet attrs) {<!--CRLF-->
41: super(context, attrs);<!--CRLF-->
42: this.setStaticTransformationsEnabled(true);<!--CRLF-->
43: }
<!--CRLF-->
44:
<!--CRLF-->
45: public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {<!--CRLF-->
46: super(context, attrs, defStyle);<!--CRLF-->
47: this.setStaticTransformationsEnabled(true);<!--CRLF-->
48: }
<!--CRLF-->
49:
<!--CRLF-->
50: /**<!--CRLF-->
51: * Get the max rotational angle of the image<!--CRLF-->
52: *<!--CRLF-->
53: * @return the mMaxRotationAngle<!--CRLF-->
54: */<!--CRLF-->
55: public int getMaxRotationAngle() {<!--CRLF-->
56: return mMaxRotationAngle;<!--CRLF-->
57: }
<!--CRLF-->
58:
<!--CRLF-->
59: /**<!--CRLF-->
60: * Set the max rotational angle of each image<!--CRLF-->
61: *<!--CRLF-->
62: * @param maxRotationAngle<!--CRLF-->
63: * the mMaxRotationAngle to set<!--CRLF-->
64: */<!--CRLF-->
65: public void setMaxRotationAngle(int maxRotationAngle) {<!--CRLF-->
66: mMaxRotationAngle = maxRotationAngle;
<!--CRLF-->
67: }
<!--CRLF-->
68:
<!--CRLF-->
69: /**<!--CRLF-->
70: * Get the Max zoom of the centre image<!--CRLF-->
71: *<!--CRLF-->
72: * @return the mMaxZoom<!--CRLF-->
73: */<!--CRLF-->
74: public int getMaxZoom() {<!--CRLF-->
75: return mMaxZoom;<!--CRLF-->
76: }
<!--CRLF-->
77:
<!--CRLF-->
78: /**<!--CRLF-->
79: * Set the max zoom of the centre image<!--CRLF-->
80: *<!--CRLF-->
81: * @param maxZoom<!--CRLF-->
82: * the mMaxZoom to set<!--CRLF-->
83: */<!--CRLF-->
84: public void setMaxZoom(int maxZoom) {<!--CRLF-->
85: mMaxZoom = maxZoom;
<!--CRLF-->
86: }
<!--CRLF-->
87:
<!--CRLF-->
88: /**<!--CRLF-->
89: * Get the Centre of the Coverflow<!--CRLF-->
90: *<!--CRLF-->
91: * @return The centre of this Coverflow.<!--CRLF-->
92: */<!--CRLF-->
93: private int getCenterOfCoverflow() {<!--CRLF-->
94: //Log.e("CoverFlow Width+Height", getWidth() + "*" + getHeight());<!--CRLF-->
95: return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2<!--CRLF-->
96: + getPaddingLeft();
<!--CRLF-->
97: }
<!--CRLF-->
98:
<!--CRLF-->
99: /**<!--CRLF-->
100: * Get the Centre of the View<!--CRLF-->
101: *<!--CRLF-->
102: * @return The centre of the given view.<!--CRLF-->
103: */<!--CRLF-->
104: private static int getCenterOfView(View view) {<!--CRLF-->
105: /*Log.e("ChildView Width+Height", view.getWidth() + "*"<!--CRLF-->
106: + view.getHeight());*/<!--CRLF-->
107: return view.getLeft() + view.getWidth() / 2;<!--CRLF-->
108: }
<!--CRLF-->
109:
<!--CRLF-->
110: /**<!--CRLF-->
111: * {@inheritDoc}<!--CRLF-->
112: *<!--CRLF-->
113: * @see #setStaticTransformationsEnabled(boolean)<!--CRLF-->
114: */<!--CRLF-->
115: protected boolean getChildStaticTransformation(View child, Transformation t) {<!--CRLF-->
116:
<!--CRLF-->
117: final int childCenter = getCenterOfView(child);<!--CRLF-->
118: final int childWidth = child.getWidth();<!--CRLF-->
119: int rotationAngle = 0;<!--CRLF-->
120:
<!--CRLF-->
121: t.clear();
<!--CRLF-->
122: t.setTransformationType(Transformation.TYPE_MATRIX);
<!--CRLF-->
123:
<!--CRLF-->
124: if (childCenter == mCoveflowCenter) {<!--CRLF-->
125: transformImageBitmap((ImageView) child, t, 0);
<!--CRLF-->
126: } else {<!--CRLF-->
127: rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);<!--CRLF-->
128: if (Math.abs(rotationAngle) > mMaxRotationAngle) {<!--CRLF-->
129: rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
<!--CRLF-->
130: : mMaxRotationAngle;
<!--CRLF-->
131: }
<!--CRLF-->
132: transformImageBitmap((ImageView) child, t, rotationAngle);
<!--CRLF-->
133: }
<!--CRLF-->
134:
<!--CRLF-->
135: return true;<!--CRLF-->
136: }
<!--CRLF-->
137:
<!--CRLF-->
138: /**<!--CRLF-->
139: * This is called during layout when the size of this view has changed. If<!--CRLF-->
140: * you were just added to the view hierarchy, you're called with the old<!--CRLF-->
141: * values of 0.<!--CRLF-->
142: *<!--CRLF-->
143: * @param w<!--CRLF-->
144: * Current width of this view.<!--CRLF-->
145: * @param h<!--CRLF-->
146: * Current height of this view.<!--CRLF-->
147: * @param oldw<!--CRLF-->
148: * Old width of this view.<!--CRLF-->
149: * @param oldh<!--CRLF-->
150: * Old height of this view.<!--CRLF-->
151: */<!--CRLF-->
152: protected void onSizeChanged(int w, int h, int oldw, int oldh) {<!--CRLF-->
153: mCoveflowCenter = getCenterOfCoverflow();
<!--CRLF-->
154: super.onSizeChanged(w, h, oldw, oldh);<!--CRLF-->
155: }
<!--CRLF-->
156:
<!--CRLF-->
157: /**<!--CRLF-->
158: * Transform the Image Bitmap by the Angle passed<!--CRLF-->
159: *<!--CRLF-->
160: * @param imageView<!--CRLF-->
161: * ImageView the ImageView whose bitmap we want to rotate<!--CRLF-->
162: * @param t<!--CRLF-->
163: * transformation<!--CRLF-->
164: * @param rotationAngle<!--CRLF-->
165: * the Angle by which to rotate the Bitmap<!--CRLF-->
166: */<!--CRLF-->
167: private void transformImageBitmap(ImageView child, Transformation t,<!--CRLF-->
168: int rotationAngle) {<!--CRLF-->
169: mCamera.save();
<!--CRLF-->
170: final Matrix imageMatrix = t.getMatrix();<!--CRLF-->
171: final int imageHeight = child.getLayoutParams().height;<!--CRLF-->
172: final int imageWidth = child.getLayoutParams().width;<!--CRLF-->
173: final int rotation = Math.abs(rotationAngle);<!--CRLF-->
174:
<!--CRLF-->
175: // 在Z轴上正向移动camera的视角,实际效果为放大图片。<!--CRLF-->
176: // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。<!--CRLF-->
177: mCamera.translate(0.0f, 0.0f, 100.0f);
<!--CRLF-->
178:
<!--CRLF-->
179: // As the angle of the view gets less, zoom in<!--CRLF-->
180: if (rotation < mMaxRotationAngle) {<!--CRLF-->
181: float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));<!--CRLF-->
182: mCamera.translate(0.0f, 0.0f, zoomAmount);
<!--CRLF-->
183: }
<!--CRLF-->
184:
<!--CRLF-->
185: // 在Y轴上旋转,对应图片竖向向里翻转。<!--CRLF-->
186: // 如果在X轴上旋转,则对应图片横向向里翻转。<!--CRLF-->
187: mCamera.rotateY(rotationAngle);
<!--CRLF-->
188: mCamera.getMatrix(imageMatrix);
<!--CRLF-->
189: // Preconcats matrix相当于右乘矩阵,Postconcats matrix相当于左乘矩阵。<!--CRLF-->
190: imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
<!--CRLF-->
191: imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
<!--CRLF-->
192: mCamera.restore();
<!--CRLF-->
193: }
<!--CRLF-->
194: }
<!--CRLF-->
ageAdapter.java 图片适配器类,用来将文件中的图片资源加载到应用程序
1: package com.android.CustomGallery;<!--CRLF-->
2:
<!--CRLF-->
3: import android.content.Context;<!--CRLF-->
4: import android.graphics.Bitmap;<!--CRLF-->
5: import android.graphics.BitmapFactory;<!--CRLF-->
6: import android.graphics.Canvas;<!--CRLF-->
7: import android.graphics.LinearGradient;<!--CRLF-->
8: import android.graphics.Matrix;<!--CRLF-->
9: import android.graphics.Paint;<!--CRLF-->
10: import android.graphics.PorterDuffXfermode;<!--CRLF-->
11: import android.graphics.Bitmap.Config;<!--CRLF-->
12: import android.graphics.PorterDuff.Mode;<!--CRLF-->
13: import android.graphics.Shader.TileMode;<!--CRLF-->
14: import android.graphics.drawable.BitmapDrawable;<!--CRLF-->
15: import android.view.View;<!--CRLF-->
16: import android.view.ViewGroup;<!--CRLF-->
17: import android.widget.BaseAdapter;<!--CRLF-->
18: import android.widget.ImageView;<!--CRLF-->
19:
<!--CRLF-->
20: /*<!--CRLF-->
21: * Copyright (C) 2010 Neil Davies<!--CRLF-->
22: *<!--CRLF-->
23: * Licensed under the Apache License, Version 2.0 (the "License");<!--CRLF-->
24: * you may not use this file except in compliance with the License.<!--CRLF-->
25: * You may obtain a copy of the License at<!--CRLF-->
26: *<!--CRLF-->
27: * http://www.apache.org/licenses/LICENSE-2.0<!--CRLF-->
28: *<!--CRLF-->
29: * Unless required by applicable law or agreed to in writing, software<!--CRLF-->
30: * distributed under the License is distributed on an "AS IS" BASIS,<!--CRLF-->
31: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<!--CRLF-->
32: * See the License for the specific language governing permissions and<!--CRLF-->
33: * limitations under the License.<!--CRLF-->
34: *<!--CRLF-->
35: * This code is base on the Android Gallery widget and was Created<!--CRLF-->
36: * by Neil Davies neild001 'at' gmail dot com to be a Coverflow widget<!--CRLF-->
37: *<!--CRLF-->
38: * @author Neil Davies<!--CRLF-->
39: */<!--CRLF-->
40: public class ImageAdapter extends BaseAdapter {<!--CRLF-->
41: int mGalleryItemBackground;<!--CRLF-->
42: private Context mContext;<!--CRLF-->
43:
<!--CRLF-->
44: private int[] mImageIds;<!--CRLF-->
45:
<!--CRLF-->
46: private ImageView[] mImages;<!--CRLF-->
47:
<!--CRLF-->
48: public ImageAdapter(Context c, int[] ImageIds) {<!--CRLF-->
49: mContext = c;
<!--CRLF-->
50: mImageIds = ImageIds;
<!--CRLF-->
51: mImages = new ImageView[mImageIds.length];<!--CRLF-->
52: }
<!--CRLF-->
53:
<!--CRLF-->
54: public boolean createReflectedImages() {<!--CRLF-->
55: // The gap we want between the reflection and the original image<!--CRLF-->
56: final int reflectionGap = 4;<!--CRLF-->
57:
<!--CRLF-->
58:
<!--CRLF-->
59:
<!--CRLF-->
60: int index = 0;<!--CRLF-->
61: for (int imageId : mImageIds) {<!--CRLF-->
62: Bitmap originalImage = BitmapFactory.decodeResource(mContext
<!--CRLF-->
63: .getResources(), imageId);
<!--CRLF-->
64: int width = originalImage.getWidth();<!--CRLF-->
65: int height = originalImage.getHeight();<!--CRLF-->
66:
<!--CRLF-->
67: // This will not scale but will flip on the Y axis<!--CRLF-->
68: Matrix matrix = new Matrix();<!--CRLF-->
69: matrix.preScale(1, -1);
<!--CRLF-->
70:
<!--CRLF-->
71: // Create a Bitmap with the flip matrix applied to it.<!--CRLF-->
72: // We only want the bottom half of the image<!--CRLF-->
73: Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
<!--CRLF-->
74: height / 2, width, height / 2, matrix, false);
<!--CRLF-->
75:
<!--CRLF-->
76: // Create a new bitmap with same width but taller to fit<!--CRLF-->
77: // reflection<!--CRLF-->
78: Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
<!--CRLF-->
79: (height + height / 2), Config.ARGB_8888);
<!--CRLF-->
80:
<!--CRLF-->
81: // Create a new Canvas with the bitmap that's big enough for<!--CRLF-->
82: // the image plus gap plus reflection<!--CRLF-->
83: Canvas canvas = new Canvas(bitmapWithReflection);<!--CRLF-->
84: // Draw in the original image<!--CRLF-->
85: canvas.drawBitmap(originalImage, 0, 0, null);
<!--CRLF-->
86: // Draw in the gap<!--CRLF-->
87: Paint deafaultPaint = new Paint();<!--CRLF-->
88: canvas.drawRect(0, height, width, height + reflectionGap,
<!--CRLF-->
89: deafaultPaint);
<!--CRLF-->
90: // Draw in the reflection<!--CRLF-->
91: canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
<!--CRLF-->
92:
<!--CRLF-->
93: // Create a shader that is a linear gradient that covers the<!--CRLF-->
94: // reflection<!--CRLF-->
95: Paint paint = new Paint();<!--CRLF-->
96: LinearGradient shader = new LinearGradient(0, originalImage<!--CRLF-->
97: .getHeight(), 0, bitmapWithReflection.getHeight()
<!--CRLF-->
98: + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
<!--CRLF-->
99: // Set the paint to use this shader (linear gradient)<!--CRLF-->
100: paint.setShader(shader);
<!--CRLF-->
101: // Set the Transfer mode to be porter duff and destination in<!--CRLF-->
102: paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));<!--CRLF-->
103: // Draw a rectangle using the paint with our linear gradient<!--CRLF-->
104: canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
<!--CRLF-->
105: + reflectionGap, paint);
<!--CRLF-->
106: //解决图片的锯齿现象<!--CRLF-->
107: BitmapDrawable bd = new BitmapDrawable(bitmapWithReflection);<!--CRLF-->
108: bd.setAntiAlias(true);
<!--CRLF-->
109:
<!--CRLF-->
110: ImageView imageView = new ImageView(mContext);<!--CRLF-->
111: //imageView.setImageBitmap(bitmapWithReflection);<!--CRLF-->
112: imageView.setImageDrawable(bd);
<!--CRLF-->
113: imageView.setLayoutParams(new GalleryFlow.LayoutParams(160, 240));<!--CRLF-->
114: // imageView.setScaleType(ScaleType.MATRIX);<!--CRLF-->
115: mImages[index++] = imageView;
<!--CRLF-->
116:
<!--CRLF-->
117: }
<!--CRLF-->
118: return true;<!--CRLF-->
119: }
<!--CRLF-->
120:
<!--CRLF-->
121: public int getCount() {<!--CRLF-->
122: return mImageIds.length;<!--CRLF-->
123: }
<!--CRLF-->
124:
<!--CRLF-->
125: public Object getItem(int position) {<!--CRLF-->
126: return position;<!--CRLF-->
127: }
<!--CRLF-->
128:
<!--CRLF-->
129: public long getItemId(int position) {<!--CRLF-->
130: return position;<!--CRLF-->
131: }
<!--CRLF-->
132:
<!--CRLF-->
133: public View getView(int position, View convertView, ViewGroup parent) {<!--CRLF-->
134:
<!--CRLF-->
135: // Use this code if you want to load from resources<!--CRLF-->
136: /*<!--CRLF-->
137: * ImageView i = new ImageView(mContext);<!--CRLF-->
138: * i.setImageResource(mImageIds[position]); i.setLayoutParams(new<!--CRLF-->
139: * CoverFlow.LayoutParams(350,350));<!--CRLF-->
140: * i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);<!--CRLF-->
141: *<!--CRLF-->
142: * //Make sure we set anti-aliasing otherwise we get jaggies<!--CRLF-->
143: * BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();<!--CRLF-->
144: * drawable.setAntiAlias(true); return i;<!--CRLF-->
145: */<!--CRLF-->
146:
<!--CRLF-->
147: return mImages[position];<!--CRLF-->
148: }
<!--CRLF-->
149:
<!--CRLF-->
150: /**<!--CRLF-->
151: * Returns the size (0.0f to 1.0f) of the views depending on the 'offset' to<!--CRLF-->
152: * the center.<!--CRLF-->
153: */<!--CRLF-->
154: public float getScale(boolean focused, int offset) {<!--CRLF-->
155: /* Formula: 1 / (2 ^ offset) */<!--CRLF-->
156: return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));<!--CRLF-->
157: }
<!--CRLF-->
158:
<!--CRLF-->
159: }
<!--CRLF-->
MainActivity.java 用来显示界面
1: package com.android.CustomGallery;<!--CRLF-->
2:
<!--CRLF-->
3: /**<!--CRLF-->
4: * 一个实现了3D效果的Gallery,就像iPhone中的相册浏览一样炫……<!--CRLF-->
5: */<!--CRLF-->
6: import android.app.Activity;<!--CRLF-->
7: import android.os.Bundle;<!--CRLF-->
8:
<!--CRLF-->
9: public class MainActivity extends Activity {<!--CRLF-->
10: /** Called when the activity is first created. */<!--CRLF-->
11: @Override
<!--CRLF-->
12: public void onCreate(Bundle savedInstanceState) {<!--CRLF-->
13: super.onCreate(savedInstanceState);<!--CRLF-->
14:
<!--CRLF-->
15: setContentView(R.layout.main);
<!--CRLF-->
16:
<!--CRLF-->
17: int[] images = { R.drawable.photo1, R.drawable.photo2,<!--CRLF-->
18: R.drawable.photo3, R.drawable.photo4, R.drawable.photo5,
<!--CRLF-->
19: R.drawable.photo6, R.drawable.photo7, R.drawable.photo8, };
<!--CRLF-->
20:
<!--CRLF-->
21: ImageAdapter adapter = new ImageAdapter(this, images);<!--CRLF-->
22: adapter.createReflectedImages();
<!--CRLF-->
23:
<!--CRLF-->
24: GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.gallery_flow);
<!--CRLF-->
25: galleryFlow.setAdapter(adapter);
<!--CRLF-->
26:
<!--CRLF-->
27: }
<!--CRLF-->
28: }
<!--CRLF-->
main.xml 程序设置文件
1: <!--l version=<span style="color: #006080" mce_style="color: #00608-->"1.0" encoding="utf-8"?><!--CRLF-->
2: "http://schemas.android.com/apk/res/android"
<!--CRLF-->
3: android:orientation="vertical"<!--CRLF-->
4: android:layout_width="fill_parent"<!--CRLF-->
5: android:layout_height="fill_parent"<!--CRLF-->
6: >
<!--CRLF-->
7:8: android:id="@+id/gallery_flow"<!--CRLF-->9: android:layout_width="fill_parent"<!--CRLF-->10: android:layout_height="fill_parent"<!--CRLF-->11: />
<!--CRLF--> <!--CRLF-->