图片的拖拽和缩放

图片的拖拽很基础也很实用,很多地方用到,直接上干货。
MainActivity.java:
package com.example.dragzoom;

import android.app.Activity;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

/**
 * 
 * @author Zls
 *实现图片的拖拽和缩放,给图片添加onClickListener
 */

public class MainActivity extends Activity {

	private ImageView image;

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

		image = (ImageView) this.findViewById(R.id.image);
		image.setOnTouchListener(new MyTouchListener());
	}

	public final class MyTouchListener implements OnTouchListener {
		private int mode = 0;									//三种模式表示触摸类型
		private static final int DRAG = 1;
		private static final int ZOOM = 2;
		private PointF startpPoint = new PointF(), midPoint;	//startPoint用来记录拖拽的时候记录第一次拖拽的点,midPoint让图片缩放的时候不移动
		private float startDis, endDis;							//两者之比表示缩放比例
		private Matrix oldMatrix = new Matrix(), newMatrix = new Matrix();		//两个矩阵

		@Override
		public boolean onTouch(View v, MotionEvent event) {
			switch (event.getAction() & MotionEvent.ACTION_MASK) {
			case MotionEvent.ACTION_DOWN:						//单手指按下表示为拖拽
				mode = DRAG;
				oldMatrix.set(image.getImageMatrix());
				startpPoint.set(event.getX(), event.getY());
				break;

			case MotionEvent.ACTION_MOVE:						// 手指在屏幕移动,该 事件会不断地触发
				if (mode == DRAG) {
					float dx = event.getX() - startpPoint.x;	// 得到在x轴的移动距离
					float dy = event.getY() - startpPoint.y;	// 得到在y轴的移动距离
					newMatrix.set(oldMatrix);					// 在没有进行移动之前的位置基础上进行移动
					newMatrix.postTranslate(dx, dy);
				} else if (mode == ZOOM) {						// 缩放
					endDis = countDis(event);					// 结束距离
					if (endDis > 10f) {
						float scale = endDis / startDis;		// 得到缩放倍数
						newMatrix.set(oldMatrix);
						newMatrix.postScale(scale, scale, midPoint.x,		//应用缩放
								midPoint.y);
					}
				}
				break;

			case MotionEvent.ACTION_UP:							//单手指或多手指抬起都恢复初始状态
			case MotionEvent.ACTION_POINTER_UP:
				mode = 0;
				break;

			case MotionEvent.ACTION_POINTER_DOWN:				//多手指按下
				mode = ZOOM;
				startDis = countDis(event);
				if (startDis > 10f) {
					midPoint = midPoint(event);
				}
				break;
			}
			image.setImageMatrix(newMatrix);					//让image显示最新的矩阵位置和大小,不执行则以上的触摸事件就无效鸟
			return true;
		}
	}

	private static PointF midPoint(MotionEvent event) {
		float dx = (event.getX(1) + event.getX(0)) / 2;
		float dy = (event.getY(1) + event.getY(0)) / 2;
		return new PointF(dx, dy);
	}

	//
	private static float countDis(MotionEvent event) {
		float a = event.getX(1) - event.getX(0);
		float b = event.getY(1) - event.getY(0);
		float c = (float) Math.sqrt(a * a + b * b);
		return c;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}


layout_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ImageView 
        android:id="@+id/image"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scaleType="matrix"
        android:src="@drawable/luobing"/>

</RelativeLayout>


ps:如果有错误希望不吝赐教。

猜你喜欢

转载自zhonglunshun.iteye.com/blog/1973178