Android 滑动放大,Android多点触控实现对图片放大缩小平移,惯性滑动等功能

文章将在原有基础之上做了一些扩展功能:

1.图片的惯性滑动

2.图片缩放小于正常比例时,松手会自动回弹成正常比例

3.图片缩放大于最大比例时,松手会自动回弹成最大比例

c48d349ec751eb98598078327600967a.gif

实现图片的缩放,平移,双击缩放等基本功能的代码如下,每一行代码我都做了详细的注释

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

//我们需要将图片宽度缩小,缩小至控件的宽度

//至于为什么要这样计算,我们可以这样想

//我们调用matrix.postScale(scale,scale)时,宽和高都要乘以scale的

//当前我们的图片宽度是dw,dw*scale=dw*(width/dw)=width,这样就等于控件宽度了

//我们的高度同时也乘以scale,这样能够保证图片的宽高比不改变,图片不变形

scale = width * 1.0f / dw;

}

//如果图片的宽度小于控件宽度,图片高度大于控件高度

if (dwheight){

//我们就应该将图片的高度缩小,缩小至控件的高度,计算方法同上

scale = height * 1.0f / dh;

}

//如果图片的宽度小于控件宽度,高度小于控件高度时,我们应该将图片放大

//比如图片宽

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值