Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能
首先推荐一下鸿洋大大的打造个性的图片预览与多点触控视频教程,这套教程教我们一步一步实现了多点触控实现对图片的平移和缩放的功能,这篇文章我将在鸿洋大大的基础之上做了一些扩展功能:
1.图片的惯性滑动
2.图片缩放小于正常比例时,松手会自动回弹成正常比例
3.图片缩放大于最大比例时,松手会自动回弹成最大比例
实现图片的缩放,平移,双击缩放等基本功能的代码如下,每一行代码我都做了详细的注释<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
public class ZoomImageView extends ImageView implements ScaleGestureDetector.OnScaleGestureListener,
View.OnTouchListener , ViewTreeObserver.OnGlobalLayoutListener{
/**
* 缩放手势的监测
*/
private ScaleGestureDetector mScaleGestureDetector;
/**
* 监听手势
*/
private GestureDetector mGestureDetector;
/**
* 对图片进行缩放平移的Matrix
*/
private Matrix mScaleMatrix;
/**
* 第一次加载图片时调整图片缩放比例,使图片的宽或者高充满屏幕
*/
private boolean mFirst;
/**
* 图片的初始化比例
*/
private float mInitScale;
/**
* 图片的最大比例
*/
private float mMaxScale;
/**
* 双击图片放大的比例
*/
private float mMidScale;
/**
* 是否正在自动放大或者缩小
*/
private boolean isAutoScale;
//-----------------------------------------------
/**
* 上一次触控点的数量
*/
private int mLastPointerCount;
/**
* 是否可以拖动
*/
private boolean isCanDrag;
/**
* 上一次滑动的x和y坐标
*/
private float mLastX;
private float mLastY;
/**
* 可滑动的临界值
*/
private int mTouchSlop;
/**
* 是否用检查左右边界
*/
private boolean isCheckLeftAndRight;
/**
* 是否用检查上下边界
*/
private boolean isCheckTopAndBottom;
public ZoomImageView(Context context) {
this(context, null, 0);
}
public ZoomImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ZoomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//一定要将图片的ScaleType设置成Matrix类型的
setScaleType(ScaleType.MATRIX);
//初始化缩放手势监听器
mScaleGestureDetector = new ScaleGestureDetector(context,this);
//初始化矩阵
mScaleMatrix = new Matrix();
setOnTouchListener(this);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
//初始化手势检测器,监听双击事件
mGestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onDoubleTap(MotionEvent e) {
//如果是正在自动缩放,则直接返回,不进行处理
if (isAutoScale) return true;
//得到点击的坐标
float x = e.getX();
float y = e.getY();
//如果当前图片的缩放值小于指定的双击缩放值
if (getScale() < mMidScale){
//进行自动放大
post(new AutoScaleRunnable(mMidScale,x,y));
}else{
//当前图片的缩放值大于初试缩放值,则自动缩小
post(new AutoScaleRunnable(mInitScale,x,y));
}
return true;
}
});
}
/**
* 当view添加到window时调用,早于onGlobalLayout,因此可以在这里注册监听器
*/
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
getViewTreeObserver().addOnGlobalLayoutListener(this);
}
/**
* 当view从window上移除时调用,因此可以在这里移除监听器
*/
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
/**
* 当布局树发生变化时会调用此方法,我们可以在此方法中获得控件的宽和高
*/
@Override
public void onGlobalLayout() {
//只有当第一次加载图片的时候才会进行初始化,用一个变量mFirst控制
if (!mFirst){
mFirst = true;
//得到控件的宽和高
int width = getWidth();
int height = getHeight();
//得到当前ImageView中加载的图片
Drawable d = getDrawable();
if(d == null){//如果没有图片,则直接返回
return;
}
//得到当前图片的宽和高,图片的宽和高不一定等于控件的宽和高
//因此我们需要将图片的宽和高与控件宽和高进行判断
//将图片完整的显示在屏幕中
int dw = d.getIntrinsicWidth();
int dh = d.getIntrinsicHeight();
//我们定义一个临时变量,根据图片与控件的宽高比例,来确定这个最终缩放值
float scale = 1.0f;
//如果图片宽度大于控件宽度,图片高度小于控件高度
if (dw>width && dh