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

                                                              

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

package nate.android.Service;
import android.content.Context;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Transformation;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;
public class MyGallery extends Gallery {
    private Camera mCamera = new Camera();
    private int mMaxRotationAngle = 45;
    private int mMaxZoom = -120;
    private int mCoveflowCenter;

    public MyGallery(Context context) {
            super(context);
            this.setStaticTransformationsEnabled(true);
    }

    public MyGallery(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.setStaticTransformationsEnabled(true);
    }

    public MyGallery(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            this.setStaticTransformationsEnabled(true);
    }

    public int getMaxRotationAngle() {
            return mMaxRotationAngle;
    }
    public void setMaxRotationAngle(int maxRotationAngle) {
            mMaxRotationAngle = maxRotationAngle;
    }
    public int getMaxZoom() {
            return mMaxZoom;
    }
    public void setMaxZoom(int maxZoom) {
            mMaxZoom = maxZoom;
    }
    private int getCenterOfCoverflow() {
            return (getWidth() - getPaddingLeft() - getPaddingRight()) / 2
                            + getPaddingLeft();
    }
    private static int getCenterOfView(View view) {
            return view.getLeft() + view.getWidth() / 2;
    }
    protected boolean getChildStaticTransformation(View child, Transformation t) {
            final int childCenter = getCenterOfView(child);
            final int childWidth = child.getWidth();
            int rotationAngle = 0;
            t.clear();
            t.setTransformationType(Transformation.TYPE_MATRIX);

            if (childCenter == mCoveflowCenter) {
                    transformImageBitmap((ImageView) child, t, 0);
            } else {
                    rotationAngle = (int) (((float) (mCoveflowCenter - childCenter) / childWidth) * mMaxRotationAngle);
                    if (Math.abs(rotationAngle) > mMaxRotationAngle) {
                            rotationAngle = (rotationAngle < 0) ? -mMaxRotationAngle
                                            : mMaxRotationAngle;
                    }
                    transformImageBitmap((ImageView) child, t, rotationAngle);
            }
            return true;
    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            mCoveflowCenter = getCenterOfCoverflow();
            super.onSizeChanged(w, h, oldw, oldh);
    }
    
    private void transformImageBitmap(ImageView child, Transformation t,
                    int rotationAngle) {
            mCamera.save();
            final Matrix imageMatrix = t.getMatrix();
            final int imageHeight = child.getLayoutParams().height;
            final int imageWidth = child.getLayoutParams().width;
            final int rotation = Math.abs(rotationAngle);

            // 在Z轴上正向移动camera的视角,实际效果为放大图片。
            // 如果在Y轴上移动,则图片上下移动;X轴上对应图片左右移动。
            mCamera.translate(0.0f, 0.0f, 100.0f);

            // As the angle of the view gets less, zoom in
            if (rotation < mMaxRotationAngle) {
                    float zoomAmount = (float) (mMaxZoom + (rotation * 1.5));
                    mCamera.translate(0.0f, 0.0f, zoomAmount);
            }
            // 在Y轴上旋转,对应图片竖向向里翻转。
            // 如果在X轴上旋转,则对应图片横向向里翻转。
            mCamera.rotateY(rotationAngle);
            mCamera.getMatrix(imageMatrix);
            imageMatrix.preTranslate(-(imageWidth / 2), -(imageHeight / 2));
            imageMatrix.postTranslate((imageWidth / 2), (imageHeight / 2));
            mCamera.restore();
    }
}


在布局文件中

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ffffff"
    >
    <LinearLayout
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:orientation="vertical" android:paddingTop="10px"
    >
     <LinearLayout
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:orientation="horizontal"
    >
    <TextView
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:id="@+id/dishName"         android:textSize="18pt"
    android:text="菜名"
    />
    <LinearLayout
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:orientation="horizontal" android:paddingLeft="10px"
    >
    <TextView
    android:layout_width="wrap_content" android:layout_height="wrap_content"
    android:id="@+id/ds"         android:textSize="18pt"
    android:text="评分 :    "
    />
    <RatingBar
    android:numStars="5" android:rating="3"
    android:stepSize="0.2" android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:isIndicator="true"
    android:id="@+id/dishScores" style="?android:attr/ratingBarStyleSmall"
    />
    </LinearLayout>
    </LinearLayout>
    <LinearLayout
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:orientation="horizontal" 
    >
    <TextView
    android:layout_width="fill_parent" android:layout_height="wrap_content"
    android:id="@+id/dishPrice" android:text="价格" android:textSize="18pt"
    />
    </LinearLayout>
    </LinearLayout>
<nate.android.Service.MyGallery
	android:id="@+id/Gallery01" 
	android:layout_width="fill_parent" 
	android:layout_height="wrap_content" 
	android:layout_centerInParent="true"
	/>
	<TextView
    android:text="\n\n\n\n这里是关于每一道菜的信息,点击图片进入评论"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/gallery01"
    android:paddingLeft="5px"
    android:id="@+id/showHint"
    />
</LinearLayout>

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

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

package nate.android.Service;

import java.util.ArrayList;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;
import android.graphics.Shader.TileMode;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

public class ImageAdapter extends BaseAdapter {

	int mGalleryItemBackground;
	private Context mContext;
	private ArrayList<byte[]> dishImages = new ArrayList<byte[]>();
	private ImageView[] mImages;
	
	public ImageAdapter(Context c,ArrayList<byte[]> tmpDishImages) {
		mContext = c;
		dishImages = tmpDishImages;
		mImages = new ImageView[dishImages.size()];
	}
	public boolean createReflectedImages() {
		final int reflectionGap = 4;
		int index = 0;
		System.out.println("dishImages size " + dishImages.size());
		for (int i =0; i < dishImages.size(); ++i ) {
			System.out.println("dishImage --- " + dishImages.get(i));
			Bitmap originalImage = BitmapFactory.decodeByteArray(dishImages.get(i), 0, dishImages.get(i).length);
			int width = originalImage.getWidth();
			int height = originalImage.getHeight();
			Matrix matrix = new Matrix();
			matrix.preScale(1, -1);
			Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
					height / 2, width, height / 2, matrix, false);
			
			Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
					(height + height / 2), Config.ARGB_8888);

			Canvas canvas = new Canvas(bitmapWithReflection);
			canvas.drawBitmap(originalImage, 0, 0, null);
			Paint deafaultPaint = new Paint();
			canvas.drawRect(0, height, width, height + reflectionGap,
					deafaultPaint);
			canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
			Paint paint = new Paint();
			LinearGradient shader = new LinearGradient(0, originalImage
					.getHeight(), 0, bitmapWithReflection.getHeight()
					+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
			paint.setShader(shader);
			paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
			canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
					+ reflectionGap, paint);
			ImageView imageView = new ImageView(mContext);
			imageView.setImageBitmap(bitmapWithReflection);
//			imageView.setLayoutParams(new GalleryFlow.LayoutParams(180, 240));
			imageView.setLayoutParams(new MyGallery.LayoutParams(270, 360));
			//imageView.setScaleType(ScaleType.MATRIX);
			mImages[index++] = imageView;
		}
		return true;
	}

	private Resources getResources() {
		return null;
	}

	public int getCount() {
		return dishImages.size();
	}

	public Object getItem(int position) {
		return position;
	}

	public long getItemId(int position) {
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		return mImages[position];
	}

	public float getScale(boolean focused, int offset) {
		return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
	}
}

在这个类中构造函数需要传入将要在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。实现上图显示的效果。

package com.nate.wte2;
import java.io.IOException;
import java.util.ArrayList;
import nate.InfoService.DishInfo;
import nate.InfoService.StoreInfoService;
import nate.InfoService.WhichChoice;
import nate.NetConnection.GetConnectionSock;
import nate.android.Service.GalleryFlow;
import nate.android.Service.ImageAdapter;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.AdapterView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import com.nate.wte.LocalSql.StoresInfoDB;
public class DishMenuActivity extends Activity {
	
	private ArrayList<DishInfo> dishInfoList = new ArrayList<DishInfo>();
	private TextView dishName;
	private RatingBar dishScores;
	private TextView dishPrice;
	//3:send the dish's whole info to fill the activity(send the comments of the dish)
	private int flag3 = 3;
	WhichChoice choice3 = new WhichChoice(flag3);
	private StoreInfoService storeInfo;
	private ProgressDialog loadingDialog;
	
	/**
	 * handler handle the dialog dismission
	 */
    private Handler handler = new Handler(){

		@Override
		public void handleMessage(Message msg) {
			loadingDialog.dismiss();
			//other operation
			super.handleMessage(msg);
		}
	};
	/**
	 * thread to load the data from local database or from the server
	 * @author Administrator
	 *
	 */
	class Loading implements Runnable{
		@Override
		public void run() {
			try {
				//这儿的sleep将换成一个循环,知道某个条件满足时候才结束循环,让dialog终止
				Thread.sleep(1500);
				handler.sendEmptyMessage(0);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * loading the items,start the thread to load
	 */
	public void loadingItems(){
		loadingDialog = ProgressDialog.show(DishMenuActivity.this, "", "loading...");
		Thread t = new Thread(new Loading());
		t.start();
	}
	
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dishmenu_gallery);
        
        StoresInfoDB infoDB;
    	int dishInfoListLength;
    	ArrayList<byte[]> dishImages = new ArrayList<byte[]>();
    	byte[] dishImage;
    	
        dishName = (TextView)this.findViewById(R.id.dishName);
        dishPrice = (TextView)this.findViewById(R.id.dishPrice);
        dishScores = (RatingBar)this.findViewById(R.id.dishScores);
        
        //得到intent中从Choices类中传过来的对象
        Intent intent = getIntent();
        Bundle bundle = intent.getBundleExtra("bundleData");
        storeInfo = (StoreInfoService)bundle.getSerializable("storeInfo");
        dishInfoList = (ArrayList<DishInfo>)bundle.getSerializable("dishInfoList");
        System.out.println("look look the info received from Choices Activity");
        for(int i = 0; i < dishInfoList.size(); i++){
        	System.out.println("---  " + i + dishInfoList.get(i).getDishImage().toString());
        }
        dishInfoListLength = dishInfoList.size();
        //初始化 dishImages
        for(int i = 0; i < dishInfoListLength; i++){
        	dishImages.add(dishInfoList.get(i).getDishImage());
        }
        System.out.println("the length of the dishImages ---- " + dishImages.size());
		
		//注意这里一段
		
        ImageAdapter adapter = new ImageAdapter(DishMenuActivity.this,dishImages);
        adapter.createReflectedImages();       
        GalleryFlow galleryFlow = (GalleryFlow) findViewById(R.id.Gallery01);
        galleryFlow.setOnItemSelectedListener(new OnItemSelectedListener(){
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				String showName = "菜名 : " + dishInfoList.get((int)arg3).getDishName() + "   ";
				dishName.setText(showName);
				dishScores.setRating(dishInfoList.get((int)arg3).getDishScores());
				dishPrice.setText("价格 :  " + dishInfoList.get((int)arg3).getPrice() + " 元\n\n\n");
			}
			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				
			}
        	
        });
        
        galleryFlow.setOnItemClickListener(new OnItemClickListener(){
		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			
			loadingItems();
			DishInfo dishInfo = dishInfoList.get((int)arg3);
			try {
				GetConnectionSock.fromClient.writeObject(choice3);
				System.out.println("send the flag 3 ");
				GetConnectionSock.fromClient.writeObject(dishInfo);
				System.out.println("send the name back to server");
				DishInfo dishComments = (DishInfo)GetConnectionSock.fromServer.readObject();
				System.out.println("recv the dish comments");
				dishInfo.setDishName(dishInfoList.get((int)arg3).getDishName());
				dishInfo.setDishComments(dishComments.getDishComments());
				System.out.println("full the dish info");
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			Intent intent = new Intent();
			Bundle bundle = new Bundle();
			bundle.putSerializable("dishInfo",dishInfo);
			bundle.putSerializable("storeInfo",storeInfo);
			intent.putExtra("dishBundleData",bundle);
			intent.setClass(DishMenuActivity.this,DishInfoDynamic.class);
			Toast.makeText(DishMenuActivity.this, "进入评论此道菜",Toast.LENGTH_LONG).show();
			DishMenuActivity.this.startActivity(intent);
		}
       });
       galleryFlow.setAdapter(adapter);  //注意这里
	}
}
在这个activity中跟本文相关的,也就是在galley中添加图片功能,只需注意上面代码中标注出来的部分代码即可,至于数据来源得到的方式都不一样,这里只要知道数据是一个ArrayList<byte[]>就行了。重要的是利用上面的MyGallery以及ImageAdapter,当然,通过简单的理解,很轻松的这两个类就能够在其他的工程中重用的 微笑


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值