Java代码:
1. package eoe.android.CustomGallery;
2.
3.
4. import android.content.Context;
5. import android.graphics.Camera;
6. import android.graphics.Matrix;
7. import android.util.AttributeSet;
8. import android.util.Log;
9. import android.view.View;
10. import android.view.animation.Transformation;
11. import android.widget.Gallery;
12. import android.widget.ImageView;
13.
14. public class GalleryFlow extends Gallery {
15.
16. /*图形的照相机ImageViews用于转换矩阵的*/
17.
18. private Camera mCamera = new Camera();
19.
20. /**这个的最大角ImageView将旋转*/
21.
22. private int mMaxRotationAngle = 60;
23.
24.
25. /**这个研究中心的最大放大效果*/
26.
27. private int mMaxZoom = -120;
28.
29. /* Coverflow的中心*/
30.
31. private int mCoveflowCenter;
32.
33.
34.
35. public GalleryFlow(Context context) {
36.
37. super(context);
38.
39. this.setStaticTransformationsEnabled(true);
40.
41. }
42.
43.
44. public GalleryFlow(Context context, AttributeSet attrs) {
45.
46. super(context, attrs);
47.
48. this.setStaticTransformationsEnabled(true);
49.
50. }
51.
52.
53. public GalleryFlow(Context context, AttributeSet attrs, int defStyle) {
54.
55. super(context, attrs, defStyle);
56.
57. this.setStaticTransformationsEnabled(true);
58.
59. }
60.
61.
62.
63. /**
64.
65. * 旋转角度得到最大的形象
66.
67. */
68.
69. public int getMaxRotationAngle() {
70.
71. return mMaxRotationAngle;
72.
73. }
74.
75.
76.
77. /**
78.
79. * 设置它的最大旋转角度的每一个图像
80.
81. */
82.
83. public void setMaxRotationAngle(int maxRotationAngle) {
84.
85. mMaxRotationAngle = maxRotationAngle;
86.
87. }
88.
89.
90.
91.
92.
93. public int getMaxZoom() {
94.
95. return mMaxZoom;
96.
97. }
98.
99.
100.
101. public void setMaxZoom(int maxZoom) {
102.
103. mMaxZoom = maxZoom;
104.
105. }
106.
107.
108.
109.
110. private int getCenterOfCoverflow() {
111.
112. //Log.e("CoverFlow Width+Height", getWidth() + "*" + getHeight());
113.
114. return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
115.
116. + getPaddingLeft();
117.
118. }
119.
120.
121.
122.
123.
124. private static int getCenterOfView(View view) {
125.
126. /*Log.e("ChildView Width+Height", view.getWidth() + "*"
127.
128. + view.getHeight());*/
129.
130. return view.getLeft() + view.getWidth() / 2;
131.
132. }
133.
134.
135.
136. protected boolean getChildStaticTransformation(View child, Transformation t) {
137.
138.
139. final int childCenter = getCenterOfView(child);
140.
141. final int childWidth = child.getWidth();
142.
143. int rotationAngle = 0;
144.
145. t.clear();
146.
147. t.setTransformationType(Transformation.TYPE_MATRIX);
148.
149.
150. if (childCenter == mCoveflowCenter) {
151.
152. transformImageBitmap((ImageView) child, t, 0);
153.
154. } else {
155.
156. rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
157.
158. if (Math.abs(rotationAngle) > mMaxRotationAngle) {
159.
160. rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
161.
162. : mMaxRotationAngle;
163.
164. }
165.
166. transformImageBitmap((ImageView) child, t, rotationAngle);
167.
168. }
169.
170.
171.
172. return true;
173.
174. }
175.
176.
177.
178. /**
179.
180. * 这就是所谓的在大小的布局时,这一观点已经发生了改变。如果
181.
182.
183. *你只是添加到视图层次,有人叫你旧的观念
184.
185. *值为0.
186.
187. *
188.
189. * @param w
190.
191. * Current width of this view.
192.
193. * @param h
194.
195. * Current height of this view.
196.
197. * @param oldw
198.
199. * Old width of this view.
200.
201. * @param oldh
202.
203. * Old height of this view.
204.
205. */
206.
207. protected void onSizeChanged(int w, int h, int oldw, int oldh) {
208.
209. mCoveflowCenter = getCenterOfCoverflow();
210.
211. super.onSizeChanged(w, h, oldw, oldh);
212.
213. }
214.
215.
216.
217. /**
218.
219. * Transform the Image Bitmap by the Angle passed
220.
221. *
222.
223. * @param imageView
224.
225. * ImageView the ImageView whose bitmap we want to rotate
226.
227. * @param t
228.
229. * transformation
230.
231. * @param rotationAngle
232.
233. * 以旋转角度的位图
234. */
235.
236. private void transformImageBitmap(ImageView child, Transformation t,
237.
238. int rotationAngle) {
239.
240. mCamera.save();
241.
242. final Matrix imageMatrix = t.getMatrix();
243.
244. final int imageHeight = child.getLayoutParams().height;
245.
246. final int imageWidth = child.getLayoutParams().width;
247.
248. final int rotation = Math.abs(rotationAngle);
249.
250.
251.
252. // 在Z轴上正向移动camera的视角,实际效果为放大图片。
253.
254. // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。
255.
256. mCamera.translate(0.0f, 0.0f, 100.0f);
257.
258.
259.
260. // 如视图的角度更少,放大
261.
262. if (rotation < mMaxRotationAngle) {
263.
264. float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
265.
266. mCamera.translate(0.0f, 0.0f, zoomAmount);
267.
268. }
269.
270.
271.
272. // 在Y轴上旋转,对应图片竖向向里翻转。
273.
274. // 如果在X轴上旋转,则对应图片横向向里翻转。
275.
276. mCamera.rotateY(rotationAngle);
277.
278. mCamera.getMatrix(imageMatrix);
279.
280. // Preconcats matrix相当于右乘矩阵,Postconcats matrix相当于左乘矩阵。
281.
282. imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
283.
284. imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
285.
286. mCamera.restore();
287.
288. }
289.
290. }
291.
复制代码
ImageAdapter.java
Java代码:
1.
2. package eoe.android.CustomGallery;
3.
4. import android.content.Context;
5. import android.graphics.Bitmap;
6. import android.graphics.BitmapFactory;
7. import android.graphics.Canvas;
8. import android.graphics.LinearGradient;
9. import android.graphics.Matrix;
10. import android.graphics.Paint;
11. import android.graphics.PorterDuffXfermode;
12. import android.graphics.Bitmap.Config;
13. import android.graphics.PorterDuff.Mode;
14. import android.graphics.Shader.TileMode;
15. import android.graphics.drawable.BitmapDrawable;
16. import android.view.View;
17. import android.view.ViewGroup;
18. import android.widget.BaseAdapter;
19. import android.widget.ImageView;
20.
21.
22.
23.
24.
25. public class ImageAdapter extends BaseAdapter {
26.
27. int mGalleryItemBackground;
28.
29. private Context mContext;
30.
31.
32. private int[] mImageIds;
33.
34. private ImageView[] mImages;
35.
36. public ImageAdapter(Context c, int[] ImageIds) {
37.
38. mContext = c;
39.
40. mImageIds = ImageIds;
41.
42. mImages = new ImageView[mImageIds.length];
43.
44. }
45.
46.
47.
48. public boolean createReflectedImages() {
49.
50. // 我们想要的差距之间的省思与原始图像
51.
52. final int reflectionGap = 4;
53.
54. int index = 0;
55.
56. for (int imageId : mImageIds) {
57.
58. Bitmap originalImage = BitmapFactory.decodeResource(mContext
59.
60. .getResources(), imageId);
61.
62. int width = originalImage.getWidth();
63.
64. int height = originalImage.getHeight();
65.
66.
67.
68. // 但这并不会将规模翻在Y轴上
69.
70. Matrix matrix = new Matrix();
71.
72. matrix.preScale(1, -1);
73.
74.
75.
76. // 创建一个位图与翻转矩阵,适用于这。
77.
78. // 我们只需要底部一半的形象
79.
80. Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
81.
82. height / 2, width, height / 2, matrix, false);
83.
84.
85.
86. // 创建一个新的位图以及相同宽度但更高的格格不入
87.
88.
89. // 反射
90.
91. Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
92.
93. (height + height / 2), Config.ARGB_8888);
94.
95.
96. Canvas canvas = new Canvas(bitmapWithReflection);
97.
98. // 画出原始图像
99. canvas.drawBitmap(originalImage, 0, 0, null);
100.
101. // 画在缝
102.
103. Paint deafaultPaint = new Paint();
104.
105. canvas.drawRect(0, height, width, height + reflectionGap,
106.
107. deafaultPaint);
108.
109. canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
110.
111. Paint paint = new Paint();
112.
113. LinearGradient shader = new LinearGradient(0, originalImage
114.
115. .getHeight(), 0, bitmapWithReflection.getHeight()
116.
117. + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
118.
119. paint.setShader(shader);
120.
121. paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
122.
123. // 画一个长方形使用油漆与我们的线性梯度
124.
125. canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
126.
127. + reflectionGap, paint);
128.
129. //解决图片的锯齿现象
130.
131. BitmapDrawable bd = new BitmapDrawable(bitmapWithReflection);
132.
133. bd.setAntiAlias(true);
134.
135. ImageView imageView = new ImageView(mContext);
136.
137. //imageView.setImageBitmap(bitmapWithReflection);
138.
139. imageView.setImageDrawable(bd);
140.
141. imageView.setLayoutParams(new GalleryFlow.LayoutParams(160, 240));
142.
143. // imageView.setScaleType(ScaleType.MATRIX);
144.
145. mImages[index++] = imageView;
146.
147. }
148.
149. return true;
150.
151. }
152.
153.
154.
155. public int getCount() {
156.
157. return mImageIds.length;
158.
159. }
160.
161.
162.
163. public Object getItem(int position) {
164.
165. return position;
166.
167. }
168.
169. public long getItemId(int position) {
170.
171. return position;
172.
173. }
174.
175. public View getView(int position, View convertView, ViewGroup parent) {
176.
177. /*
178.
179. * ImageView i = new ImageView(mContext);
180.
181. * i.setImageResource(mImageIds[position]); i.setLayoutParams(new
182.
183. * CoverFlow.LayoutParams(350,350));
184.
185. * i.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
186.
187. *
188.
189. * //Make sure we set anti-aliasing otherwise we get jaggies
190.
191. * BitmapDrawable drawable = (BitmapDrawable) i.getDrawable();
192.
193. * drawable.setAntiAlias(true); return i;
194.
195. */
196.
197. return mImages[position];
198.
199. }
200.
201. public float getScale(boolean focused, int offset) {
202.
203. /* Formula: 1 / (2 ^ offset) */
204.
205. return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
206.
207. }
208.
209.
210. }
211.
复制代码
MainActivity.java
Java代码:
1. package com.android.CustomGallery;
2.
3. /**
4.
5. * 一个实现了3D效果的Gallery,就像iPhone中的相册浏览一样炫……
6.
7. */
8.
9. import android.app.Activity;
10. import android.os.Bundle;
11.
12.
13.
14. public class MainActivity extends Activity {
15.
16. /** Called when the activity is first created. */
17.
18. @Override
19.
20. public void onCreate(Bundle savedInstanceState) {
21.
22. super.onCreate(savedInstanceState);
23.
24. setContentView(R.layout.main);
25.
26. int[] images = { R.drawable.photo1, R.drawable.photo2,
27.
28. R.drawable.photo3, R.drawable.photo4, R.drawable.photo5,
29.
30. R.drawable.photo6, R.drawable.photo7, R.drawable.photo8, };
31.
32.
33.
34. ImageAdapter adapter = new ImageAdapter(this, images);
35.
36. adapter.createReflectedImages();
37.
38.
39.
40. GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.gallery_flow);
41.
42. galleryFlow.setAdapter(adapter);
43.
44. }
45.
46. }
47.
复制代码
main.xml
Java代码:
1. <?xml version="1.0" encoding="utf-8"?>
2.
3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
4.
5. android:orientation="vertical"
6.
7. android:layout_width="fill_parent"
8.
9. android:layout_height="fill_parent"
10.
11. >
12.
13. <com.android.CustomGallery.GalleryFlow
14.
15. android:id="@+id/gallery_flow"
16.
17. android:layout_width="fill_parent"
18.
19. android:layout_height="fill_parent"
20.
21. />
22.
23. </LinearLayout>