现在的位置: 首页 > 综合 > 正文

android 动态向Gallery中添加图片及倒影&&3D效果

2012年11月17日 ⁄ 综合 ⁄ 共 8480字 ⁄ 字号 评论关闭

                                                  

在android中gallery可以提供一个很好的显示图片的方式,实现上面的效果以及动态添加数据库或者网络上下载下来的图片资源。我们首先实现一个自定义的Gallery类。

MyGallery.java

  1 package nate.android.Service;
2 import android.content.Context;
3 import android.graphics.Camera;
4 import android.graphics.Matrix;
5 import android.graphics.Rect;
6 import android.util.AttributeSet;
7 import android.view.View;
8 import android.view.animation.Transformation;
9 import android.widget.Gallery;
10 import android.widget.ImageView;
11 import android.widget.Toast;
12 public class MyGallery extends Gallery {
13 private Camera mCamera = new Camera();
14 private int mMaxRotationAngle = 45;
15 private int mMaxZoom = -120;
16 private int mCoveflowCenter;
17
18 public MyGallery(Context context) {
19 super(context);
20 this.setStaticTransformationsEnabled(true);
21 }
22
23 public MyGallery(Context context, AttributeSet attrs) {
24 super(context, attrs);
25 this.setStaticTransformationsEnabled(true);
26 }
27
28 public MyGallery(Context context, AttributeSet attrs, int defStyle) {
29 super(context, attrs, defStyle);
30 this.setStaticTransformationsEnabled(true);
31 }
32
33 public int getMaxRotationAngle() {
34 return mMaxRotationAngle;
35 }
36 public void setMaxRotationAngle(int maxRotationAngle) {
37 mMaxRotationAngle = maxRotationAngle;
38 }
39 public int getMaxZoom() {
40 return mMaxZoom;
41 }
42 public void setMaxZoom(int maxZoom) {
43 mMaxZoom = maxZoom;
44 }
45 private int getCenterOfCoverflow() {
46 return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
47 + getPaddingLeft();
48 }
49 private static int getCenterOfView(View view) {
50 return view.getLeft() + view.getWidth() / 2;
51 }
52 protected boolean getChildStaticTransformation(View child, Transformation t) {
53 final int childCenter = getCenterOfView(child);
54 final int childWidth = child.getWidth();
55 int rotationAngle = 0;
56 t.clear();
57 t.setTransformationType(Transformation.TYPE_MATRIX);
58
59 if (childCenter == mCoveflowCenter) {
60 transformImageBitmap((ImageView) child, t, 0);
61 } else {
62 rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
63 if (Math.abs(rotationAngle) > mMaxRotationAngle) {
64 rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
65 : mMaxRotationAngle;
66 }
67 transformImageBitmap((ImageView) child, t, rotationAngle);
68 }
69 return true;
70 }
71
72 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
73 mCoveflowCenter = getCenterOfCoverflow();
74 super.onSizeChanged(w, h, oldw, oldh);
75 }
76
77 private void transformImageBitmap(ImageView child, Transformation t,
78 int rotationAngle) {
79 mCamera.save();
80 final Matrix imageMatrix = t.getMatrix();
81 final int imageHeight = child.getLayoutParams().height;
82 final int imageWidth = child.getLayoutParams().width;
83 final int rotation = Math.abs(rotationAngle);
84
85 // 在Z轴上正向移动camera的视角,实际效果为放大图片。
86 // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。
87 mCamera.translate(0.0f, 0.0f, 100.0f);
88
89 // As the angle of the view gets less, zoom in
90 if (rotation < mMaxRotationAngle) {
91 float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
92 mCamera.translate(0.0f, 0.0f, zoomAmount);
93 }
94 // 在Y轴上旋转,对应图片竖向向里翻转。
95 // 如果在X轴上旋转,则对应图片横向向里翻转。
96 mCamera.rotateY(rotationAngle);
97 mCamera.getMatrix(imageMatrix);
98 imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
99 imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
100 mCamera.restore();
101 }
102 }

  

  在布局文件中

View Code

 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 android:background="#ffffff"
7 >
8 <LinearLayout
9 android:layout_width="fill_parent" android:layout_height="wrap_content"
10 android:orientation="vertical" android:paddingTop="10px"
11 >
12 <LinearLayout
13 android:layout_width="fill_parent" android:layout_height="wrap_content"
14 android:orientation="horizontal"
15 >
16 <TextView
17 android:layout_width="wrap_content" android:layout_height="wrap_content"
18 android:id="@+id/dishName" android:textSize="18pt"
19 android:text="菜名"
20 />
21 <LinearLayout
22 android:layout_width="fill_parent" android:layout_height="wrap_content"
23 android:orientation="horizontal" android:paddingLeft="10px"
24 >
25 <TextView
26 android:layout_width="wrap_content" android:layout_height="wrap_content"
27 android:id="@+id/ds" android:textSize="18pt"
28 android:text="评分 : "
29 />
30 <RatingBar
31 android:numStars="5" android:rating="3"
32 android:stepSize="0.2" android:layout_width="wrap_content"
33 android:layout_height="wrap_content" android:isIndicator="true"
34 android:id="@+id/dishScores" style="?android:attr/ratingBarStyleSmall"
35 />
36 </LinearLayout>
37 </LinearLayout>
38 <LinearLayout
39 android:layout_width="fill_parent" android:layout_height="wrap_content"
40 android:orientation="horizontal"
41 >
42 <TextView
43 android:layout_width="fill_parent" android:layout_height="wrap_content"
44 android:id="@+id/dishPrice" android:text="价格" android:textSize="18pt"
45 />
46 </LinearLayout>
47 </LinearLayout>
48 <nate.android.Service.MyGallery
49 android:id="@+id/Gallery01"
50 android:layout_width="fill_parent"
51 android:layout_height="wrap_content"
52 android:layout_centerInParent="true"
53 />
54 <TextView
55 android:text="\n\n\n\n这里是关于每一道菜的信息,点击图片进入评论"
56 android:layout_width="fill_parent"
57 android:layout_height="wrap_content"
58 android:layout_below="@+id/gallery01"
59 android:paddingLeft="5px"
60 android:id="@+id/showHint"
61 />
62 </LinearLayout>

  

  在上面的XML文件中,我们使用了自定义的MyGallery。

然后顶一个ImageAdapter类继承自BaseAdapter。

View Code

 1 package nate.android.Service;
2
3 import java.util.ArrayList;
4 import android.content.Context;
5 import android.content.res.Resources;
6 import android.graphics.Bitmap;
7 import android.graphics.BitmapFactory;
8 import android.graphics.Canvas;
9 import android.graphics.LinearGradient;
10 import android.graphics.Matrix;
11 import android.graphics.Paint;
12 import android.graphics.PorterDuffXfermode;
13 import android.graphics.Bitmap.Config;
14 import android.graphics.PorterDuff.Mode;
15 import android.graphics.Shader.TileMode;
16 import android.view.View;
17 import android.view.ViewGroup;
18 import android.widget.BaseAdapter;
19 import android.widget.ImageView;
20
21 public class ImageAdapter extends BaseAdapter {
22
23 int mGalleryItemBackground;
24 private Context mContext;
25 private ArrayList<byte[]> dishImages = new ArrayList<byte[]>();
26 private ImageView[] mImages;
27
28 public ImageAdapter(Context c,ArrayList<byte[]> tmpDishImages) {
29 mContext = c;
30 dishImages = tmpDishImages;
31 mImages = new ImageView[dishImages.size()];
32 }
33 public boolean createReflectedImages() {
34 final int reflectionGap = 4;
35 int index = 0;
36 System.out.println("dishImages size " + dishImages.size());
37 for (int i =0; i < dishImages.size(); ++i ) {
38 System.out.println("dishImage --- " + dishImages.get(i));
39 Bitmap originalImage = BitmapFactory.decodeByteArray(dishImages.get(i), 0, dishImages.get(i).length);
40 int width = originalImage.getWidth();
41 int height = originalImage.getHeight();
42 Matrix matrix = new Matrix();
43 matrix.preScale(1, -1);
44 Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
45 height / 2, width, height / 2, matrix, false);
46
47 Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
48 (height + height / 2), Config.ARGB_8888);
49
50 Canvas canvas = new Canvas(bitmapWithReflection);
51 canvas.drawBitmap(originalImage, 0, 0, null);
52 Paint deafaultPaint = new Paint();
53 canvas.drawRect(0, height, width, height + reflectionGap,
54 deafaultPaint);
55 canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
56 Paint paint = new Paint();
57 LinearGradient shader = new LinearGradient(0, originalImage
58 .getHeight(), 0, bitmapWithReflection.getHeight()
59 + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
60 paint.setShader(shader);
61 paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
62 canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
63 + reflectionGap, paint);
64 ImageView imageView = new ImageView(mContext);
65 imageView.setImageBitmap(bitmapWithReflection);
66 // imageView.setLayoutParams(new GalleryFlow.LayoutParams(180, 240));
67 imageView.setLayoutParams(new MyGallery.LayoutParams(270, 360));
68 //imageView.setScaleType(ScaleType.MATRIX);
69 mImages[index++] = imageView;
70 }
71 return true;
72 }
73
74 private Resources getResources() {
75 return null;
76 }
77
78 public int getCount() {
79 return dishImages.size();
80 }
81
82 public Object getItem(int position) {
83 return position;
84 }
85
86 public long getItemId(int position) {
87 return position;
88 }
89
90 public View getView(int position, View convertView, ViewGroup parent) {
91 return mImages[position];
92 }
93
94 public float getScale(boolean focused, int offset) {
95 return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
96 }
97 }

  

在这个类中构造函数需要传入将要在gallery中绘制的图片数据,(以byte[]类型的为例,因为我在存入sqlite以及从从网络下载下来的图片demo中都将其转成byte[]),同样我们使用

Bitmap originalImage = BitmapFactory.decodeByteArray(dishImages.get(i), 0, dishImages.get(i).length);

在这篇文章有较详细的说明

将byte[]类型的图片数据“还原”。byte[]类型的图片源数据保存在一个ArrayList<byte[]>当中。这样我们为动态的实现在gallery中添加图片提供数据来源。

在下面的activity中使用我们自定义的baseAdapter以及Gallery。实现上图显示的效果。

使用实例类
  1 package com.nate.wte2;
2

抱歉!评论已关闭.