Android ImageView 手勢控制放大縮小 滑屏切換

主要思路是創建兩個事件監聽,

一個手勢監聽MyGuestListner繼承SimpleOnGestureListener,負責雙擊圖片後爲ImageView設置新的放大縮小移動監聽以及滑屏切換圖片。

一個MulitPointTouchListener繼承OnTouchListener,負責圖片的放大縮小移動以及雙擊後還原圖片大小和卸載ImageView當前監聽。


放大縮小監聽類

package com.dawnpro.dfacmobile.cpzs;

import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.Toast;

import com.dawnpro.dfacmobile.utils.Global;

public class MulitPointTouchListener implements OnTouchListener {   
        //圖像矩陣,用於縮放移動等圖像操作
        Matrix matrix = new Matrix();   
        Matrix savedMatrix = new Matrix();
        Matrix originMatrix = new Matrix();
  
        //點擊或者手勢操作類型
        static final int NONE = 0;   
        static final int DRAG = 1;   
        static final int ZOOM = 2;   
        int mode = NONE;   
  
        //PointF 爲座標值的float形式
        PointF start = new PointF();   
        PointF mid = new PointF();   
        float oldDist = 1f;
        
        //判斷是否雙擊的變量
        //點擊計數
        private int count = 0;
        //第一次點擊的時間
        private long firstTouch;
        //第二次點擊的時間
        private long secondTouch;
        
        //本張海報第一次點擊
        private boolean first = true;
        
        @Override  
        public boolean onTouch(View v, MotionEvent event) {
        	
                ImageView view = (ImageView) v;   
  
                // 處理接受到的事件
                switch (event.getAction() & MotionEvent.ACTION_MASK) {
                //單手指(主)點擊下觸發
                case MotionEvent.ACTION_DOWN:
                		//判斷是否雙擊
                		count ++;
                		if(count == 1){
                			//記錄第一次點擊的時間
                			firstTouch = System.currentTimeMillis();
                		}else if(count == 2){
                			//記錄第二次點擊的時間
                			secondTouch = System.currentTimeMillis();
                			
                			if((secondTouch - firstTouch) < 600){
                				//兩次點擊小於600毫秒,則爲雙擊事件,去除該操作listener並還原圖片爲初始狀態
                				view.setImageMatrix(originMatrix);
                				view.setOnTouchListener(null);
                				Toast.makeText(Global.applicationContext, "縮放模式關閉,請滑屏切換圖片", Toast.LENGTH_SHORT).show();
                			}
                			
                			count = 0;
                			firstTouch = 0;
                			secondTouch = 0;
                		}
                		
                		//記錄圖片初始大小
                		if(first){
                			//本張海報第一次點擊
                			originMatrix.set(view.getImageMatrix());
                			first = false;
                		}
  
                        matrix.set(view.getImageMatrix());
                        savedMatrix.set(matrix);
                        //記錄點擊下的座標
                        start.set(event.getX(), event.getY());   
                        // 爲拖動模式
                        mode = DRAG;   
                        break;
                //第二個手指(副)點擊下觸發。多點觸控
                case MotionEvent.ACTION_POINTER_DOWN:
                		//計算兩個手指之間的距離
                        oldDist = spacing(event);
                        //如果距離大於10,則定多點觸控
                        if (oldDist > 10f) {
                        		//保存當前matrix
                                savedMatrix.set(matrix);
                                //計算點擊下的兩點的中間點座標
                                midPoint(mid, event);
                                mode = ZOOM;   
                        }   
                        break;   
                case MotionEvent.ACTION_UP:   
                case MotionEvent.ACTION_POINTER_UP:   
                        mode = NONE;   
  
                        break;   
                case MotionEvent.ACTION_MOVE:
                		//如果爲單指點擊並且移動,爲拖拽圖片進行產看
                        if (mode == DRAG) {
                        	Log.i("jerry","action drag ... ");
//                              // ...   
                                matrix.set(savedMatrix);
                                //通過matrix移動圖片
                                matrix.postTranslate(event.getX() - start.x, event.getY()   
                                                - start.y);   
                        } else if (mode == ZOOM) {
                        		//計算兩點間距離
                                float newDist = spacing(event);   
                                if (newDist > 10f) {   
                                        matrix.set(savedMatrix);
                                        //計算縮放比
                                        float scale = newDist / oldDist;
                                        //縮放操作
                                        matrix.postScale(scale, scale, mid.x, mid.y);   
                                }   
                        }   
                        break;   
                }   
  
                view.setImageMatrix(matrix);   
                return true; //告知事件已被處理  
        }   
  
        //計算點擊後兩點間距離
        private float spacing(MotionEvent event) {   
                float x = event.getX(0) - event.getX(1);   
                float y = event.getY(0) - event.getY(1);   
                return (float) Math.sqrt(x * x + y * y);
        }   
  
        //計算兩點間中間點的座標
        private void midPoint(PointF point, MotionEvent event) {   
                float x = event.getX(0) + event.getX(1);   
                float y = event.getY(0) + event.getY(1);   
                point.set(x / 2, y / 2);   
        }   
}  

Activity兼滑動監聽


package com.dawnpro.dfacmobile.cpzs;

import java.io.InputStream;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.dawnpro.dfacmobile.R;
import com.dawnpro.dfacmobile.utils.ActivityUtils;
import com.dawnpro.dfacmobile.utils.Constant;
import com.dawnpro.dfacmobile.utils.Global;

public class SpecialtyActivity extends Activity {
	// imageloader
	// private ImageLoader imageLoader;

	//
	Bitmap btp;
	//
	MulitPointTouchListener mulitPointTouchListener;

	// 手勢相關
	private GestureDetector detector;
	// 標題欄
	private TextView tv_title;
	// 特點圖片集合
	private int[] images;
	//
	private ImageView iv_specialtyImage;
	// 特色海報頁數
	private int page = 0;
	//
	private boolean notZoom = true;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_specialty);

		detector = new GestureDetector(this, new MyGuestListner());

		// imageLoader = ImageLoader.getInstance();

		Intent intent = getIntent();
		String title = intent.getStringExtra("title");

		initImage(title);

		init(title);
	}

	/**
	 * 初始化界面
	 */
	private void init(String title) {

		// 設置標題欄
		tv_title = (TextView) findViewById(R.id.title_name);
		tv_title.setText(title + "- 特點");

		iv_specialtyImage = (ImageView) findViewById(R.id.specialty_image);
		mulitPointTouchListener = new MulitPointTouchListener();
		setImage(page);
	}

	private void setImage(int page) {
		// images[page]爲資源ID數組中的資源ID
		InputStream is = this.getResources().openRawResource(images[page]);
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = false;
		// 圖片大小縮放比例,建議爲2的倍數,這裏圖片尺寸沒有縮放
		// options.inSampleSize = 1;
		btp = BitmapFactory.decodeStream(is, null, options);
		
		// 將生成的 bitmap設置到目標imageView
		iv_specialtyImage.setImageBitmap(btp);
		LayoutParams ps = iv_specialtyImage.getLayoutParams();
		ps.width = Global.screen_width;
		ps.height = Global.screen_height;
		iv_specialtyImage.setLayoutParams(ps);
	}

	/**
	 * 提醒GC回收
	 */
	private void recycleImage() {
		if (!btp.isRecycled()) {
			btp.recycle();
			btp = null;
			System.gc(); // 提醒系統及時回收
		}
	}

	/**
	 * 準備產品特點圖片集
	 */
	private void initImage(String title) {

		if (title.equals(Constant.KPT)) {
			// 凱普特
			images = new int[] { R.drawable.kpts1, R.drawable.kpts2,
					R.drawable.kpts3, R.drawable.kpts4 };
		} else if (title.equals(Constant.DLK)) {
			images = new int[] { R.drawable.dlks1, R.drawable.dlks2,
					R.drawable.dlks3 };
		} else if (title.equals(Constant.FRK)) {
			images = new int[] { R.drawable.frks1, R.drawable.frks2,
					R.drawable.frks3, R.drawable.frks4, R.drawable.frks5,
					R.drawable.frks6 };
		}
	}

	public void click(View view) {
		int id = view.getId();

		switch (id) {
		case R.id.specialty_image:
			pageNext();
			break;

		case R.id.back_cpzs:
			ActivityUtils.closeCurrentActivity(this);
			break;

		default:
			break;
		}
	}

	/**
	 * 海報翻頁
	 */
	private void pageNext() {
		page++;
		if (page > (images.length - 1)) {
			page = 0;
		}

		// 釋放
		recycleImage();
		// 設置
		setImage(page);
	}

	private void prePage() {
		page--;
		if (page < 0) {
			page = images.length - 1;
		}

		recycleImage();
		setImage(page);
	}

	/**
	 * 滑動監聽類
	 * 
	 * @author dpjiangyb
	 * 
	 */
	class MyGuestListner extends SimpleOnGestureListener {

		/**
		 * 雙擊事件
		 */
		@Override
		public boolean onDoubleTap(MotionEvent e) {
			Log.i("jerry", "雙擊了一次 ... ");
			if(notZoom){
				iv_specialtyImage.setOnTouchListener(mulitPointTouchListener);
				notZoom = false;
				Toast.makeText(Global.applicationContext, "開啓縮放模式,雙指控制縮放", Toast.LENGTH_SHORT).show();
			}else{
				iv_specialtyImage.setOnTouchListener(null);
				notZoom = true;
			}
			return true;
		}

		// 監聽滑動事件
		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
				float velocityY) {

			if (e1.getX() - e2.getX() > 120) {
				// 向左滑動
				pageNext();
				ActivityUtils.animationPushInFromRight(SpecialtyActivity.this,
						iv_specialtyImage);
			} else if (e1.getX() - e2.getX() < -120) {
				// 向右滑動
				prePage();
				ActivityUtils.animationPushInFromLeft(SpecialtyActivity.this,
						iv_specialtyImage);
			} else {
				return false;
			}

			return true;
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return detector.onTouchEvent(event);
	}
}



發佈了36 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章