您的位置:首页 > 移动开发 > Android开发

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

2012-10-08 09:53 591 查看





在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 import java.io.IOException;
  3 import java.util.ArrayList;
  4 import nate.InfoService.DishInfo;
  5 import nate.InfoService.StoreInfoService;
  6 import nate.InfoService.WhichChoice;
  7 import nate.NetConnection.GetConnectionSock;
  8 import nate.android.Service.GalleryFlow;
  9 import nate.android.Service.ImageAdapter;
 10 import android.app.Activity;
 11 import android.app.ProgressDialog;
 12 import android.content.Intent;
 13 import android.os.Bundle;
 14 import android.os.Handler;
 15 import android.os.Message;
 16 import android.view.View;
 17 import android.widget.AdapterView;
 18 import android.widget.RatingBar;
 19 import android.widget.TextView;
 20 import android.widget.Toast;
 21 import android.widget.AdapterView.OnItemClickListener;
 22 import android.widget.AdapterView.OnItemSelectedListener;
 23 import com.nate.wte.LocalSql.StoresInfoDB;
 24 public class DishMenuActivity extends Activity {
 25     
 26     private ArrayList<DishInfo> dishInfoList = new ArrayList<DishInfo>();
 27     private TextView dishName;
 28     private RatingBar dishScores;
 29     private TextView dishPrice;
 30     //3:send the dish's whole info to fill the activity(send the comments of the dish)
 31     private int flag3 = 3;
 32     WhichChoice choice3 = new WhichChoice(flag3);
 33     private StoreInfoService storeInfo;
 34     private ProgressDialog loadingDialog;
 35     
 36     /**
 37      * handler handle the dialog dismission
 38      */
 39     private Handler handler = new Handler(){
 40 
 41         @Override
 42         public void handleMessage(Message msg) {
 43             loadingDialog.dismiss();
 44             //other operation
 45             super.handleMessage(msg);
 46         }
 47     };
 48     /**
 49      * thread to load the data from local database or from the server
 50      * @author Administrator
 51      *
 52      */
 53     class Loading implements Runnable{
 54         @Override
 55         public void run() {
 56             try {
 57                 //这儿的sleep将换成一个循环,知道某个条件满足时候才结束循环,让dialog终止
 58                 Thread.sleep(1500);
 59                 handler.sendEmptyMessage(0);
 60             } catch (InterruptedException e) {
 61                 e.printStackTrace();
 62             }
 63         }
 64     }
 65     
 66     /**
 67      * loading the items,start the thread to load
 68      */
 69     public void loadingItems(){
 70         loadingDialog = ProgressDialog.show(DishMenuActivity.this, "", "loading...");
 71         Thread t = new Thread(new Loading());
 72         t.start();
 73     }
 74     
 75     
 76     public void onCreate(Bundle savedInstanceState) {
 77         super.onCreate(savedInstanceState);
 78         setContentView(R.layout.dishmenu_gallery);
 79         
 80         StoresInfoDB infoDB;
 81         int dishInfoListLength;
 82         ArrayList<byte[]> dishImages = new ArrayList<byte[]>();
 83         byte[] dishImage;
 84         
 85         dishName = (TextView)this.findViewById(R.id.dishName);
 86         dishPrice = (TextView)this.findViewById(R.id.dishPrice);
 87         dishScores = (RatingBar)this.findViewById(R.id.dishScores);
 88         
 89         //得到intent中从Choices类中传过来的对象
 90         Intent intent = getIntent();
 91         Bundle bundle = intent.getBundleExtra("bundleData");
 92         storeInfo = (StoreInfoService)bundle.getSerializable("storeInfo");
 93         dishInfoList = (ArrayList<DishInfo>)bundle.getSerializable("dishInfoList");
 94         System.out.println("look look the info received from Choices Activity");
 95         for(int i = 0; i < dishInfoList.size(); i++){
 96             System.out.println("---  " + i + dishInfoList.get(i).getDishImage().toString());
 97         }
 98         dishInfoListLength = dishInfoList.size();
 99         //初始化 dishImages
100         for(int i = 0; i < dishInfoListLength; i++){
101             dishImages.add(dishInfoList.get(i).getDishImage());
102         }
103         System.out.println("the length of the dishImages ---- " + dishImages.size());
104         ////////////////////////////////
105         //注意这里一段
106         ////////////////////////////////
107         ImageAdapter adapter = new ImageAdapter(DishMenuActivity.this,dishImages);
108         adapter.createReflectedImages();       
109         GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.Gallery01);
110         galleryFlow.setOnItemSelectedListener(new OnItemSelectedListener(){
111             @Override
112             public void onItemSelected(AdapterView<?> arg0, View arg1,
113                     int arg2, long arg3) {
114                 String showName = "菜名 : " + dishInfoList.get((int)arg3).getDishName() + "   ";
115                 dishName.setText(showName);
116                 dishScores.setRating(dishInfoList.get((int)arg3).getDishScores());
117                 dishPrice.setText("价格 :  " + dishInfoList.get((int)arg3).getPrice() + " 元\n\n\n");
118             }
119             @Override
120             public void onNothingSelected(AdapterView<?> arg0) {
121                 
122             }
123             
124         });
125         
126         galleryFlow.setOnItemClickListener(new OnItemClickListener(){
127         @Override
128         public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
129                 long arg3) {
130             
131             loadingItems();
132             DishInfo dishInfo = dishInfoList.get((int)arg3);
133             try {
134                 GetConnectionSock.fromClient.writeObject(choice3);
135                 System.out.println("send the flag 3 ");
136                 GetConnectionSock.fromClient.writeObject(dishInfo);
137                 System.out.println("send the name back to server");
138                 DishInfo dishComments = (DishInfo)GetConnectionSock.fromServer.readObject();
139                 System.out.println("recv the dish comments");
140                 dishInfo.setDishName(dishInfoList.get((int)arg3).getDishName());
141                 dishInfo.setDishComments(dishComments.getDishComments());
142                 System.out.println("full the dish info");
143             } catch (IOException e) {
144                 e.printStackTrace();
145             } catch (ClassNotFoundException e) {
146                 e.printStackTrace();
147             }
148             Intent intent = new Intent();
149             Bundle bundle = new Bundle();
150             bundle.putSerializable("dishInfo",dishInfo);
151             bundle.putSerializable("storeInfo",storeInfo);
152             intent.putExtra("dishBundleData",bundle);
153             intent.setClass(DishMenuActivity.this,DishInfoDynamic.class);
154             Toast.makeText(DishMenuActivity.this, "进入评论此道菜",Toast.LENGTH_LONG).show();
155             DishMenuActivity.this.startActivity(intent);
156         }
157        });
158        galleryFlow.setAdapter(adapter);  //注意这里
159     }
160 }




 

在这个activity中跟本文相关的,也就是在galley中添加图片功能,只需注意上面代码中标注出来的部分代码即可,至于数据来源得到的方式都不一样,这里只要知道数据是一个ArrayList<byte[]>就行了。重要的是利用上面的MyGallery以及ImageAdapter,当然,通过简单的理解,很轻松的这两个类就能够在其他的工程中重用的

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: