多触点放大缩小的画廊(MutiTouchGallery)

效果图1

 

效果图2

 

效果图3

 

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.cn.npass.nj"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".MainActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


mutitouch_gallery.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <com.cn.npass.nj.MyGallery
        android:id="@+id/gallery"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:spacing="20px" />

</RelativeLayout>

 

MainActivity.java

package com.cn.npass.nj;

import android.app.Activity;
import android.os.Bundle;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.Gallery;
import android.widget.ImageButton;

/**
 * 多点触控的放大缩小
 * 
 */
public class MainActivity extends Activity implements OnTouchListener {
	// 屏幕宽度
	public static int screenWidth;
	// 屏幕高度
	public static int screenHeight;
	private MyGallery gallery;

	private float beforeLenght = 0.0f; // 两触点距离
	private float afterLenght = 0.0f; // 两触点距离
	private boolean isScale = false;// 是否缩放
	private float currentScale = 1.0f;// 当前图片的缩放比率

	private int _position = 0;// 当前为第一张

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.mutitouch_gallery);

		gallery = (MyGallery) findViewById(R.id.gallery);

		gallery.setVerticalFadingEdgeEnabled(false);// 取消竖直渐变边框
		gallery.setHorizontalFadingEdgeEnabled(false);// 取消水平渐变边框
		gallery.setAdapter(new GalleryAdapter(this));
		gallery.setSelection(_position);// 开始选中的是第一张

		screenWidth = getWindow().getWindowManager().getDefaultDisplay()
				.getWidth();
		screenHeight = getWindow().getWindowManager().getDefaultDisplay()
				.getHeight();


	}

	private OnClickListener mOnClickListener = new OnClickListener() {

		@Override
		public void onClick(View v) {

		}

	};

	private class GalleryChangeListener implements OnItemSelectedListener {

		@Override
		public void onItemSelected(AdapterView<?> arg0, View arg1,
				int position, long id) {
			currentScale = 1.0f;// 当前缩放的比例
			isScale = false;// 是否缩放
			beforeLenght = 0.0f;// 两触点距离
			afterLenght = 0.0f;// 两触点距离

			_position = position;
		}

		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
			// TODO Auto-generated method stub

		}

	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {

		// Log.i("","touched---------------");
		switch (event.getAction() & MotionEvent.ACTION_MASK) {
		case MotionEvent.ACTION_POINTER_DOWN:// 多点缩放
			beforeLenght = spacing(event);
			if (beforeLenght > 5f) {
				isScale = true;
			}
			break;
		case MotionEvent.ACTION_MOVE:// 单点移动
			if (isScale) {
				afterLenght = spacing(event);
				if (afterLenght < 5f)
					break;
				float gapLenght = afterLenght - beforeLenght;
				if (gapLenght == 0) {
					break;
				} else if (Math.abs(gapLenght) > 5f) {
					// FrameLayout.LayoutParams params =
					// (FrameLayout.LayoutParams) gallery.getLayoutParams();
					float scaleRate = gapLenght / 854;// 缩放比例
					// Log.i("",
					// "scaleRate:"+scaleRate+" currentScale:"+currentScale);
					// Log.i("", "缩放比例:" +
					// scaleRate+" 当前图片的缩放比例:"+currentScale);
					// params.height=(int)(800*(scaleRate+1));
					// params.width=(int)(480*(scaleRate+1));
					// params.height = 400;
					// params.width = 300;
					// gallery.getChildAt(0).setLayoutParams(new
					// Gallery.LayoutParams(300, 300));
					Animation myAnimation_Scale = new ScaleAnimation(
							currentScale, currentScale + scaleRate,
							currentScale, currentScale + scaleRate,
							Animation.RELATIVE_TO_SELF, 0.5f,
							Animation.RELATIVE_TO_SELF, 0.5f);
					// Animation myAnimation_Scale = new
					// ScaleAnimation(currentScale, 1+scaleRate, currentScale,
					// 1+scaleRate);
					myAnimation_Scale.setDuration(100);
					myAnimation_Scale.setFillAfter(true);
					myAnimation_Scale.setFillEnabled(true);
					// gallery.getChildAt(0).startAnimation(myAnimation_Scale);

					// gallery.startAnimation(myAnimation_Scale);
					currentScale = currentScale + scaleRate;
					// gallery.getSelectedView().setLayoutParams(new
					// Gallery.LayoutParams((int)(480), (int)(800)));
					// Log.i("",
					// "===========:::"+gallery.getSelectedView().getLayoutParams().height);
					// gallery.getSelectedView().getLayoutParams().height=(int)(800*(currentScale));
					// gallery.getSelectedView().getLayoutParams().width=(int)(480*(currentScale));
					gallery.getSelectedView().setLayoutParams(
							new Gallery.LayoutParams(
									(int) (480 * (currentScale)),
									(int) (854 * (currentScale))));
					// gallery.getSelectedView().setLayoutParams(new
					// Gallery.LayoutParams((int)(320*(scaleRate+1)),
					// (int)(480*(scaleRate+1))));
					// gallery.getSelectedView().startAnimation(myAnimation_Scale);
					// isScale = false;
					beforeLenght = afterLenght;
				}
				return true;
			}
			break;
		case MotionEvent.ACTION_POINTER_UP:
			isScale = false;
			break;
		}

		return false;
	}

	/**
	 * 就算两点间的距离
	 */
	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);
	}
}

 


MyGallery.java

package com.cn.npass.nj;

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.View.OnTouchListener;
import android.widget.Gallery;

public class MyGallery  extends Gallery {
	private GestureDetector mGestureDetector;//GestureDetector为手势识别类
	private MyImageViewTouchBase mMyImageView;

	public MyGallery(Context context) {
		super(context);

	}

	public MyGallery(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public MyGallery(Context context, AttributeSet attrs) {
		super(context, attrs);
		mGestureDetector = new GestureDetector(new MySimpleGesture());
		
		this.setOnTouchListener(new OnTouchListener() {
			float baseValue;//原始大小
			float originalScale;//原比例
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				View view = MyGallery.this.getSelectedView();
				if (view instanceof MyImageViewTouchBase) {
					mMyImageView = (MyImageViewTouchBase) view;
					if (event.getAction() == MotionEvent.ACTION_DOWN) {
						baseValue = 0;
						originalScale = mMyImageView.getScale();
					}
					if (event.getAction() == MotionEvent.ACTION_MOVE) {
						if (event.getPointerCount() == 2) {
							float x = event.getX(0) - event.getX(1);
							float y = event.getY(0) - event.getY(1);
							float value = (float) Math.sqrt(x * x + y * y);// 计算两点的距离
							// System.out.println("value:" + value);
							if (baseValue == 0) {
								baseValue = value;
							} else {
								float scale = value / baseValue;// 当前两点间的距离除以手指落下时两点间的距离就是需要缩放的比例。
								// scale the image
								mMyImageView.zoomTo(originalScale * scale, x + event.getX(1), y + event.getY(1));

							}
						}
					}
				}
				return false;
			}

		});
	}
	
	
	
	
	/**
	 * 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发
	 * 参数解释:
		  e1:第1个ACTION_DOWN MotionEvent   
	      e2:最后一个ACTION_MOVE MotionEvent   
	      velocityX:X轴上的移动速度,像素/秒   
	      velocityY:Y轴上的移动速度,像素/秒     
	 */
	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
		View view = MyGallery.this.getSelectedView();
		if (view instanceof MyImageViewTouchBase) {
			mMyImageView = (MyImageViewTouchBase) view;

			float v[] = new float[9];
			Matrix m = mMyImageView.getImageMatrix();
			m.getValues(v);
			// 图片实时的上下左右坐标
			float left, right;
			// 图片的实时宽,高
			float width, height;
			width = mMyImageView.getScale() * mMyImageView.getImageWidth();
			height = mMyImageView.getScale() * mMyImageView.getImageHeight();
			// 一下逻辑为移动图片和滑动gallery换屏的逻辑。如果没对整个框架了解的非常清晰,改动以下的代码前请三思!!!!!!
			if ((int) width <= MainActivity.screenWidth && (int) height <= MainActivity.screenHeight)// 如果图片当前大小<屏幕大小,直接处理滑屏事件
			{
				super.onScroll(e1, e2, distanceX, distanceY);
			} else {
				left = v[Matrix.MTRANS_X];
				right = left + width;
				Rect r = new Rect();
				mMyImageView.getGlobalVisibleRect(r);

				if (distanceX > 0)// 向左滑动
				{
					if (r.left > 0) {// 判断当前ImageView是否显示完全
						super.onScroll(e1, e2, distanceX, distanceY);
					} else if (right < MainActivity.screenWidth) {
						super.onScroll(e1, e2, distanceX, distanceY);
					} else {
						mMyImageView.postTranslate(-distanceX, -distanceY);
					}
				} else if (distanceX < 0)// 向右滑动
				{
					if (r.right < MainActivity.screenWidth) {
						super.onScroll(e1, e2, distanceX, distanceY);
					} else if (left > 0) {
						super.onScroll(e1, e2, distanceX, distanceY);
					} else {
						mMyImageView.postTranslate(-distanceX, -distanceY);
					}
				}

			}

		} else {
			super.onScroll(e1, e2, distanceX, distanceY);
		}
		return false;
	}
	/**
	 * 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOV
	 * 参数解释:
		  e1:第1个ACTION_DOWN MotionEvent   
	      e2:最后一个ACTION_MOVE MotionEvent   
	      velocityX:X轴上的移动速度,像素/秒   
	      velocityY:Y轴上的移动速度,像素/秒  
	 */
	@Override
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
		return false;
	}

	/** 
     * 当发现屏幕触控事件的时候,首先出发此方法,再通过此方法,监听具体的整件 
     * 在onTouch()方法中,我们调用GestureDetector的onTouchEvent()方法,
     * 将捕捉到的MotionEvent交给GestureDetector 来分析是否有合适的callback函数来处理用户的手势 
     */ 
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		mGestureDetector.onTouchEvent(event);
		switch (event.getAction()) {
		case MotionEvent.ACTION_UP:
			// 判断上下边界是否越界
			View view = MyGallery.this.getSelectedView();
			if (view instanceof MyImageViewTouchBase) {
				mMyImageView = (MyImageViewTouchBase) view;
				float width = mMyImageView.getScale() * mMyImageView.getImageWidth();
				float height = mMyImageView.getScale() * mMyImageView.getImageHeight();
				if ((int) width <= MainActivity.screenWidth && (int) height <= MainActivity.screenHeight)// 如果图片当前大小<屏幕大小,判断边界
				{
					break;
				}
				float v[] = new float[9];
				Matrix m = mMyImageView.getImageMatrix();
				m.getValues(v);
				float top = v[Matrix.MTRANS_Y];
				float bottom = top + height;
				if (top > 0) {
					mMyImageView.postTranslateDur(-top, 200f);
				}
				Log.i("manga", "bottom:" + bottom);
				if (bottom < MainActivity.screenHeight) {
					mMyImageView.postTranslateDur(MainActivity.screenHeight - bottom, 200f);
				}

			}
			break;
		}
		return super.onTouchEvent(event);
	}

	/**
	 * 匿名内部类
	 * @Copyright:Copyright (c) 2011
	 * @Company: Shenzhen Shengxunda Tech Co.,Ltd
	 */
	private class MySimpleGesture extends SimpleOnGestureListener {
		// 按两下的第二下Touch down时触发
		public boolean onDoubleTap(MotionEvent e) {
			View view = MyGallery.this.getSelectedView();
			if (view instanceof MyImageViewTouchBase) {
				mMyImageView = (MyImageViewTouchBase) view;
				if (mMyImageView.getScale() > mMyImageView.getScaleRate()) {
					mMyImageView.zoomTo(mMyImageView.getScaleRate(), MainActivity.screenWidth / 2, MainActivity.screenHeight / 2, 200f);
					// imageView.layoutToCenter();
				} else {
					mMyImageView.zoomTo(1.0f, MainActivity.screenWidth / 2, MainActivity.screenHeight / 2, 200f);
				}

			} else {

			}
			return true;
		}
	}
}


GalleryAdapter.java

package com.cn.npass.nj;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.Gallery;

public class GalleryAdapter extends BaseAdapter {

	private Context context;

	public GalleryAdapter(Context context) {
		this.context = context;
	}

	@Override
	public int getCount() {
		return AppConstant.images.length;
	}

	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		Bitmap bmp = BitmapFactory.decodeResource(context.getResources(),
				AppConstant.images[position]);
		MyImageViewTouchBase view = new MyImageViewTouchBase(context, bmp.getWidth(),
				bmp.getHeight());
		view.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.FILL_PARENT));
		view.setImageBitmap(bmp);
		return view;
		
		/*if(position<0){
	       position = position+ images.length;
	    }*/
		
		
		/* 创建一个ImageView对象 */
	      /*ImageView i = new ImageView(this.myContext);
	      i.setPadding(10, 10, 10, 10);
	      i.setAlpha(80);
	      // i.setImageResource(this.myImageIds[position]);
	      if(position<0){
	        position = position+ images.length;
	      }
	      i.setImageResource(this.images[position% images.length]);
	      i.setScaleType(ImageView.ScaleType.FIT_XY);
	      i.setBackgroundResource(mGalleryItemBackground);
	       设置这个ImageView对象的宽高,单位为dip 
	      i.setLayoutParams(new Gallery.LayoutParams(85, 72));
	      return i;*/
	}

}


 

MyImageViewTouchBase.java

package com.cn.npass.nj;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.ImageView;
/**
 * ImageViewTouchBase
 * 此类是一个抽象类,继承自imageView,实现了放大缩小zoom,平移pan等方法.
 * 主要用到Matrix类.
 *
 */
public class MyImageViewTouchBase extends ImageView {
	@SuppressWarnings("unused")
	private static final String TAG = "ImageViewTouchBase";

	protected Matrix mBaseMatrix = new Matrix();//用于显示原始的image的基础变换矩阵

	protected Matrix mSuppMatrix = new Matrix();//存储用户对图形产生的缩放平移变换的外加的矩阵

	private final Matrix mDisplayMatrix = new Matrix();//基本矩阵加上额外的交换矩阵产生的最终矩阵

	private final float[] mMatrixValues = new float[9];

	protected Bitmap image = null;

	private int mThisWidth = -1, mThisHeight = -1;

	private float mMaxZoom = 2.0f;// 最大缩放比例
	private float mMinZoom;// 最小缩放比例

	private int imageWidth;// 图片的原始宽度
	private int imageHeight;// 图片的原始高度

	private float scaleRate;// 图片适应屏幕的缩放比例

	public MyImageViewTouchBase(Context context, int imageWidth, int imageHeight) {
		super(context);
		this.imageHeight = imageHeight;
		this.imageWidth = imageWidth;
		init();
	}

	public MyImageViewTouchBase(Context context, AttributeSet attrs,
			int imageWidth, int imageHeight) {
		super(context, attrs);
		this.imageHeight = imageHeight;
		this.imageWidth = imageWidth;
		init();
	}

	/**
	 * 计算图片要适应屏幕需要缩放的比例
	 */
	private void arithScaleRate() {
		float scaleWidth = MainActivity.screenWidth / (float) imageWidth;
		float scaleHeight = MainActivity.screenHeight / (float) imageHeight;
		scaleRate = Math.min(scaleWidth, scaleHeight);
	}

	public float getScaleRate() {
		return scaleRate;
	}

	public int getImageWidth() {
		return imageWidth;
	}

	public void setImageWidth(int imageWidth) {
		this.imageWidth = imageWidth;
	}

	public int getImageHeight() {
		return imageHeight;
	}

	public void setImageHeight(int imageHeight) {
		this.imageHeight = imageHeight;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
			event.startTracking();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
				&& !event.isCanceled()) {
			if (getScale() > 1.0f) {
				zoomTo(1.0f);
				return true;
			}
		}
		return super.onKeyUp(keyCode, event);
	}

	protected Handler mHandler = new Handler();

	@Override
	public void setImageBitmap(Bitmap bitmap) {
		super.setImageBitmap(bitmap);
		image = bitmap;
		// 计算适应屏幕的比例
		arithScaleRate();
		// 缩放到屏幕大小
		zoomTo(scaleRate, MainActivity.screenWidth / 2f,
				MainActivity.screenHeight / 2f);

		// 居中
		layoutToCenter();

		// imageView.zoomTo(scaleRate, Main.screenWidth / 2, Main.screenHeight /
		// 2
		// center(true, true);
	}

	// Center as much as possible in one or both axis. Centering is
	// defined as follows: if the image is scaled down below the
	// view's dimensions then center it (literally). If the image
	// is scaled larger than the view and is translated out of view
	// then translate it back into view (i.e. eliminate black bars).
	protected void center(boolean horizontal, boolean vertical) {
		// if (mBitmapDisplayed.getBitmap() == null) {
		// return;
		// }
		if (image == null) {
			return;
		}

		Matrix m = getImageViewMatrix();

		RectF rect = new RectF(0, 0, image.getWidth(), image.getHeight());
		// RectF rect = new RectF(0, 0, imageWidth*getScale(),
		// imageHeight*getScale());

		m.mapRect(rect);

		float height = rect.height();
		float width = rect.width();

		float deltaX = 0, deltaY = 0;

		if (vertical) {
			int viewHeight = getHeight();
			if (height < viewHeight) {
				deltaY = (viewHeight - height) / 2 - rect.top;
			} else if (rect.top > 0) {
				deltaY = -rect.top;
			} else if (rect.bottom < viewHeight) {
				deltaY = getHeight() - rect.bottom;
			}
		}

		if (horizontal) {
			int viewWidth = getWidth();
			if (width < viewWidth) {
				deltaX = (viewWidth - width) / 2 - rect.left;
			} else if (rect.left > 0) {
				deltaX = -rect.left;
			} else if (rect.right < viewWidth) {
				deltaX = viewWidth - rect.right;
			}
		}

		postTranslate(deltaX, deltaY);
		setImageMatrix(getImageViewMatrix());
	}

	private void init() {
		setScaleType(ImageView.ScaleType.MATRIX);
	}

	/**
	 * 设置图片居中显示
	 */
	public void layoutToCenter() {
		// 正在显示的图片实际宽高
		float width = imageWidth * getScale();
		float height = imageHeight * getScale();

		// 空白区域宽高
		float fill_width = MainActivity.screenWidth - width;
		float fill_height = MainActivity.screenHeight - height;

		// 需要移动的距离
		float tran_width = 0f;
		float tran_height = 0f;

		if (fill_width > 0)
			tran_width = fill_width / 2;
		if (fill_height > 0)
			tran_height = fill_height / 2;

		postTranslate(tran_width, tran_height);
		setImageMatrix(getImageViewMatrix());
	}

	protected float getValue(Matrix matrix, int whichValue) {
		matrix.getValues(mMatrixValues);
		mMinZoom = (MainActivity.screenWidth / 2f) / imageWidth;

		return mMatrixValues[whichValue];
	}

	// Get the scale factor out of the matrix.
	protected float getScale(Matrix matrix) {
		return getValue(matrix, Matrix.MSCALE_X);
	}

	protected float getScale() {
		return getScale(mSuppMatrix);
	}

	// Combine the base matrix and the supp matrix to make the final matrix.
	protected Matrix getImageViewMatrix() {
		// The final matrix is computed as the concatentation of the base matrix
		// and the supplementary matrix.
		mDisplayMatrix.set(mBaseMatrix);
		mDisplayMatrix.postConcat(mSuppMatrix);
		return mDisplayMatrix;
	}

	static final float SCALE_RATE = 1.25F;

	// Sets the maximum zoom, which is a scale relative to the base matrix. It
	// is calculated to show the image at 400% zoom regardless of screen or
	// image orientation. If in the future we decode the full 3 megapixel image,
	// rather than the current 1024x768, this should be changed down to 200%.
	protected float maxZoom() {
		if (image == null) {
			return 1F;
		}

		float fw = (float) image.getWidth() / (float) mThisWidth;
		float fh = (float) image.getHeight() / (float) mThisHeight;
		float max = Math.max(fw, fh) * 4;
		return max;
	}

	protected void zoomTo(float scale, float centerX, float centerY) {
		if (scale > mMaxZoom) {
			scale = mMaxZoom;
		} else if (scale < mMinZoom) {
			scale = mMinZoom;
		}

		float oldScale = getScale();
		float deltaScale = scale / oldScale;

		mSuppMatrix.postScale(deltaScale, deltaScale, centerX, centerY);
		setImageMatrix(getImageViewMatrix());
		center(true, true);
	}

	protected void zoomTo(final float scale, final float centerX,
			final float centerY, final float durationMs) {
		final float incrementPerMs = (scale - getScale()) / durationMs;
		final float oldScale = getScale();
		final long startTime = System.currentTimeMillis();

		mHandler.post(new Runnable() {
			public void run() {
				long now = System.currentTimeMillis();
				float currentMs = Math.min(durationMs, now - startTime);
				float target = oldScale + (incrementPerMs * currentMs);
				zoomTo(target, centerX, centerY);
				if (currentMs < durationMs) {
					mHandler.post(this);
				}
			}
		});
	}

	protected void zoomTo(float scale) {
		float cx = getWidth() / 2F;
		float cy = getHeight() / 2F;

		zoomTo(scale, cx, cy);
	}

	protected void zoomToPoint(float scale, float pointX, float pointY) {
		float cx = getWidth() / 2F;
		float cy = getHeight() / 2F;

		panBy(cx - pointX, cy - pointY);
		zoomTo(scale, cx, cy);
	}

	protected void zoomIn() {
		zoomIn(SCALE_RATE);
	}

	protected void zoomOut() {
		zoomOut(SCALE_RATE);
	}

	protected void zoomIn(float rate) {
		if (getScale() >= mMaxZoom) {
			return; // Don't let the user zoom into the molecular level.
		} else if (getScale() <= mMinZoom) {
			return;
		}
		if (image == null) {
			return;
		}

		float cx = getWidth() / 2F;
		float cy = getHeight() / 2F;

		mSuppMatrix.postScale(rate, rate, cx, cy);
		setImageMatrix(getImageViewMatrix());
	}

	protected void zoomOut(float rate) {
		if (image == null) {
			return;
		}

		float cx = getWidth() / 2F;
		float cy = getHeight() / 2F;

		// Zoom out to at most 1x.
		Matrix tmp = new Matrix(mSuppMatrix);
		tmp.postScale(1F / rate, 1F / rate, cx, cy);

		if (getScale(tmp) < 1F) {
			mSuppMatrix.setScale(1F, 1F, cx, cy);
		} else {
			mSuppMatrix.postScale(1F / rate, 1F / rate, cx, cy);
		}
		setImageMatrix(getImageViewMatrix());
		center(true, true);
	}

	public void postTranslate(float dx, float dy) {
		mSuppMatrix.postTranslate(dx, dy);
		setImageMatrix(getImageViewMatrix());
	}

	float _dy = 0.0f;

	protected void postTranslateDur(final float dy, final float durationMs) {
		_dy = 0.0f;
		final float incrementPerMs = dy / durationMs;
		final long startTime = System.currentTimeMillis();
		mHandler.post(new Runnable() {
			public void run() {
				long now = System.currentTimeMillis();
				float currentMs = Math.min(durationMs, now - startTime);

				postTranslate(0, incrementPerMs * currentMs - _dy);
				_dy = incrementPerMs * currentMs;

				if (currentMs < durationMs) {
					mHandler.post(this);
				}
			}
		});
	}

	protected void panBy(float dx, float dy) {
		postTranslate(dx, dy);
		setImageMatrix(getImageViewMatrix());
	}
}



AppConstant.java

public class AppConstant {
	public static int images[] = { R.drawable.a1, R.drawable.a2, R.drawable.a3,
			R.drawable.a4, R.drawable.a5, R.drawable.a6 };

}


 

资源下载地址为:http://download.csdn.net/detail/niejing654092427/4507415

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值