1. 程式人生 > >Android自定義View實現圖片顯示,並實現縮放、拖拽、切換功能

Android自定義View實現圖片顯示,並實現縮放、拖拽、切換功能

這裡貼三個檔案的原始碼,第一個是main.java

package com.example.test;

import java.util.ArrayList;
import java.util.List;

import com.example.test.MyXZ;
import com.example.test.R;
import com.example.test.ZoomListener;
import com.example.test.test;
import com.example.test.R.drawable;
import com.example.test.R.id;
import com.example.test.R.layout;
import com.example.test.ZoomListener.Swiper;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;

public class main extends Activity {
	/** Called when the activity is first created. */
	private Bitmap mBitmap;
	private List<Bitmap> mlist;
	

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Bitmap m1=BitmapFactory.decodeResource(getResources(), R.drawable.m1);
		Bitmap m2=BitmapFactory.decodeResource(getResources(), R.drawable.m2);
		Bitmap m3=BitmapFactory.decodeResource(getResources(), R.drawable.m3);
		Bitmap m4=BitmapFactory.decodeResource(getResources(), R.drawable.m4);
		Bitmap m5=BitmapFactory.decodeResource(getResources(), R.drawable.m5);
		Bitmap m6=BitmapFactory.decodeResource(getResources(), R.drawable.m6);
		Bitmap m7=BitmapFactory.decodeResource(getResources(), R.drawable.m7);
		Bitmap m8=BitmapFactory.decodeResource(getResources(), R.drawable.m8);
		mlist=new ArrayList<Bitmap>();
		mlist.add(m1);
		mlist.add(m2);
		mlist.add(m3);
		mlist.add(m4);
		mlist.add(m5);
		mlist.add(m6);
		mlist.add(m7);
		mlist.add(m8);
		final test tt=(test) this.getApplication();
		this.setContentView(R.layout.activity_main);
		MyXZ iv=(MyXZ) findViewById(R.id.myXZ1);
		iv.setImage(mlist.get(tt.getCurr()));
		iv.update();
		ZoomListener zl=new ZoomListener();
		Swiper swp=new Swiper(){

			@Override
			public void Swipe(View v, float length) {
				// TODO 自動生成的方法存根
				if(Math.abs(length)>20){
					int Curr=tt.getCurr();
					int i=length>0?1:-1;
					
					if(Curr+i<0){
						Curr=mlist.size()-1;
					}else if(Curr+i>=mlist.size()){
						Curr=0;
					}else{
						Curr+=i;
					}
					tt.setCurr(Curr);
				((MyXZ)v).setImage(mlist.get(Curr));
				}
			}
			
		};
		zl.setSwp(swp);
		iv.setOnTouchListener(zl);
		

	}
	 
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (mBitmap != null)
		{
			mBitmap.recycle();
			
		}

	}

	
	
}

第二個未見為ZoomListenner.java
package com.example.test;

import android.graphics.PointF;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class ZoomListener implements OnTouchListener {
	float Ospace;
	PointF start = new PointF(0, 0);
	String Mode;
	private Swiper swp;

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		// TODO 自動生成的方法存根

		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_DOWN:
			start.set(event.getX(), event.getY());
			Log.i("info", start.x + ":" + start.y);
			Mode = "DRAG";
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
			Ospace = spacing(event);
			Mode = "ZOOM";
			Log.i("info", "原始面積" + Ospace);

			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_POINTER_UP:
			Mode = "NONE";
			if(((MyXZ) v).getZoom() == 1){
				float sx = start.x - event.getX();
				float sy = start.y - event.getY();
				if (Math.abs(sx) > Math.abs(sy)) {
					swp.Swipe(v, sx/10);
				}
			}
			start.set(event.getX(), event.getY());
			break;
		case MotionEvent.ACTION_MOVE:
			if (Mode == "DRAG") {
				
				if (((MyXZ) v).getZoom() > 1) {
					float sx = start.x - event.getX();
					float sy = start.y - event.getY();
					if(Math.sqrt(sx*sx+sy*sy)>20){
					((MyXZ) v).setPan((int) (start.x - event.getX()),
							(int) (start.y - event.getY()));
					Log.i("info", "平移:" + ((MyXZ) v).getPan().x + ":"
							+ ((MyXZ) v).getPan().y);
					start.set(event.getX(), event.getY());
					}
					
				} 
			
				

			} else if (Mode == "ZOOM") {
				float nspace = spacing(event);
				float zoom = 1 + (nspace - Ospace) / Ospace;
					if(Math.abs(nspace - Ospace)>3){
					((MyXZ) v).setZoom(zoom);
					Log.i("Info", "縮放為:" + ((MyXZ) v).getZoom());
					Ospace=nspace;
					}
				
			}
			break;
	
		}
		return true;
	}

	private float spacing(MotionEvent event) {
		float x = event.getX(0) - event.getX(1);
		float y = event.getY(0) - event.getY(1);
		return FloatMath.sqrt(x * x + y * y);
	}

	public Swiper getSwp() {
		return swp;
	}

	public void setSwp(Swiper swp) {
		this.swp = swp;
	}

	public interface Swiper {
		public void Swipe(View v, float length);
	}
}

第三個為自定義的View MyXZ.java
package com.example.test;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

public class MyXZ extends View {
	private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
	private final Rect SrcRect = new Rect();
	private final Rect DstRect = new Rect();
	private float RecentZoom = 1;
	private float Zoom = 1;
	private Point Pan = new Point(0, 0);
	private Bitmap mBitmap;

	public MyXZ(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (mBitmap != null) {
			UpdateRZ();
			canvas.drawBitmap(mBitmap, SrcRect, DstRect, mPaint);
		}
	}

	private void UpdateRZ() {
		if (mBitmap != null) {
			float bw = mBitmap.getWidth();
			float bh = mBitmap.getHeight();
			float Sw = getWidth();
			float Sh = getHeight();
			if (bw * (Sh / bh) <= Sw) {
				RecentZoom = Sh / bh;
			}
			if (bh * (Sw / bw) <= Sh) {
				RecentZoom = Sw / bw;
			}
			int DesX = (int) Math.min(mBitmap.getWidth() * RecentZoom
					* getZoom(), getWidth());
			int DesY = (int) Math.min(mBitmap.getHeight() * RecentZoom
					* getZoom(), getHeight());
			int ResX = Math.round(DesX / RecentZoom / getZoom());
			int ResY = Math.round(DesY / RecentZoom / getZoom());
			if (Pan.x + (bw - ResX) / 2 < 0) {
				Pan.x = -((int) (bw - ResX) / 2);
			}
			if (Pan.y + (bh - ResY) / 2 < 0) {
				Pan.y = -((int) ((bh - ResY) / 2));
			}
			if (ResX + (Pan.x + (bw - ResX) / 2) > bw) {
				Pan.x = (int) ((bw - ResX) / 2);
			}
			if (ResY + Pan.y + (bh - ResY) / 2 > bh) {
				Pan.y = (int) ((bh - ResY) / 2);
			}
			SrcRect.left = (int) (Pan.x + (bw - ResX) / 2);
			SrcRect.top = (int) (Pan.y + (bh - ResY) / 2);
			SrcRect.right = (int) (ResX + (Pan.x + (bw - ResX) / 2));
			SrcRect.bottom = (int) (ResY + Pan.y + (bh - ResY) / 2);
			DstRect.left = (getWidth() - DesX) / 2;
			DstRect.right = (getWidth() - DesX) / 2 + DesX;
			DstRect.top = (getHeight() - DesY) / 2;
			DstRect.bottom = (getHeight() - DesY) / 2 + DesY;
		}
	}

	public void setPan(int x, int y) {
		Pan.x += x * getZoom() * RecentZoom;
		Pan.y += y * getZoom() * RecentZoom;
		update();
	}

	public Point getPan() {
		return Pan;
	}

	public void update() {
		UpdateRZ();
		invalidate();
	}

	public void setImage(Bitmap bitmap) {
		mBitmap = bitmap;
		UpdateRZ();
		invalidate();
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);
		UpdateRZ();
	}

	public float getZoom() {
		return Zoom;
	}

	public void setZoom(float zoom) {
		if (RecentZoom < 1) {
			if (zoom * Zoom >= 1) {
				Zoom *= zoom;
				if (Zoom >= 1/ RecentZoom) {
					Zoom = 1/ RecentZoom;
				}
			} else {
				Zoom = 1;
			}
		} else {
			Zoom = 1;
		}
		update();
	}
}

詳細的就不多說了,有興趣想了解詳細內容的,可以到我的個人網站下載原始碼檢視:http://www.nuatar.com/Article.aspx?id=d69f35891c0840278bed7a2e12b7b050

轉載請註明出處!!