软件编程
位置:首页>> 软件编程>> Android编程>> Android实现ImageView图片双击放大及缩小

Android实现ImageView图片双击放大及缩小

作者:BetterLaterThanNever  发布时间:2022-04-07 10:34:06 

标签:Android,ImageView,图片放大,图片缩小

本文实例介绍了Android实现ImageView图片双击放大及缩小的相关技巧,分享给大家供大家参考,具体内容如下


public class DoubleScaleImageView extends ImageView implements OnTouchListener, OnGlobalLayoutListener {
 private boolean isFirst = false;
 private float doubleScale;// 双击放大的值
 private Matrix mScaleMatrix;
 private float defaultScale;// 默认的缩放值
 private int mLastPinterCount;// 记录上一次多点触控的数量
 private float mLastX;
 private float mLastY;
 private int mTouchSlop;
 private boolean isCanDrag;
 private boolean isCheckLeft;
 private boolean isCheckTop;
 private GestureDetector mGestureDetector;
 public DoubleScaleImageView(Context context) {
   this(context, null);
 }
 public DoubleScaleImageView(Context context, AttributeSet attrs) {
   this(context, attrs, 0);
 }
 @SuppressLint("ClickableViewAccessibility")
 public DoubleScaleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
   super(context, attrs, defStyleAttr);
   mScaleMatrix = new Matrix();
   setScaleType(ScaleType.MATRIX);
   setOnTouchListener(this);
   // getScaledTouchSlop是一个距离,表示滑动的时候,手的移动要大于这个距离才开始移动控件。如果小于这个距离就不触发移动控件
   mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
   mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
     @Override
     public boolean onDoubleTap(MotionEvent e) {
       float x = e.getX();
       float y = e.getY();
       if (getScale() < doubleScale) {
         mScaleMatrix.postScale(doubleScale / getScale(), doubleScale / getScale(), x, y);// 放大
       }
       else {
         mScaleMatrix.postScale(defaultScale / getScale(), defaultScale / getScale(), x, y);// 缩小
       }
       setImageMatrix(mScaleMatrix);
       return super.onDoubleTap(e);
     }
   });
 }
 @Override
 protected void onAttachedToWindow() {// view附加到窗体上时调用该方法
   super.onAttachedToWindow();
   getViewTreeObserver().addOnGlobalLayoutListener(this);
 }
 @SuppressWarnings("deprecation")
 @Override
 protected void onDetachedFromWindow() {// 将视图从窗体上分离的时候调用该方法。
   super.onDetachedFromWindow();
   getViewTreeObserver().removeGlobalOnLayoutListener(this);
 }
 @Override
 public void onGlobalLayout() {// 在这个方法中获取ImageView加载完成后的图片
   if (!isFirst) {
     // 获取控件的宽度和高度
     int width = getWidth();
     int height = getHeight();
     // 得到我们的图片以及图片的宽度及高度
     Drawable drawable = getDrawable();
     if (drawable == null) { return; }
     int imageWidth = drawable.getIntrinsicWidth();// 图片的宽度
     int imageHeight = drawable.getIntrinsicHeight();// 图片的高度
     float scale = 1.0f;
     // 如果图片宽度大于控件宽度,但是图片高度小于控件 高度,我们要缩小图片
     if (imageWidth > width && imageHeight < height) {
       scale = width * 1.0f / imageWidth;
     }
     // 如果图片宽度小于控件宽度,但是图片高度大于控件 高度,我们要缩小图片
     if (imageWidth < width && imageHeight > height) {
       scale = height * 1.0f / imageHeight;
     }
     // 如果图片的宽度都 大于或小于控件宽度,我们则要对图片进行对应缩放,保证图片占满控件
     if ((imageWidth > width && imageHeight > height) || (imageWidth < width && imageHeight < height)) {
       scale = Math.min(width * 1.0f / imageWidth, height * 1.0f / imageHeight);
     }
     // 初始化对应的缩放值
     defaultScale = scale;
     doubleScale = defaultScale * 2;
     // 图片缩放后,将图片要移动到控件中心
     int dx = width / 2 - imageWidth / 2;
     int dy = height / 2 - imageHeight / 2;
     mScaleMatrix.postTranslate(dx, dy);
     mScaleMatrix.postScale(defaultScale, defaultScale, width / 2, height / 2);
     setImageMatrix(mScaleMatrix);
     isFirst = true;
   }
 }
 @SuppressLint("ClickableViewAccessibility")
 @Override
 public boolean onTouch(View v, MotionEvent event) {
   if (mGestureDetector.onTouchEvent(event)) { return true; }
   float x = 0;
   float y = 0;
   int pointerCount = event.getPointerCount();// 获取放在屏幕上的手指数量
   for (int i = 0; i < pointerCount; i++) {
     x += event.getX(i);
     y += event.getY(i);
   }
   x /= pointerCount;
   y /= pointerCount;
   if (mLastPinterCount != pointerCount) {
     isCanDrag = false;
     mLastX = x;
     mLastY = y;

}
   mLastPinterCount = pointerCount;
   switch (event.getAction()) {
     case MotionEvent.ACTION_MOVE:
       float dx = x - mLastX;
       float dy = y - mLastY;
       isCanDrag = isMove(dx, dy);
       if (isCanDrag) {
         RectF rectf = getMatrixRectf();
         if (null != getDrawable()) {
           isCheckLeft = isCheckTop = true;
           if (rectf.width() < getWidth()) {// 如果图片宽度小于控件宽度(屏幕宽度)不允许横向移动
             dx = 0;
             isCheckLeft = false;
           }
           if (rectf.height() < getHeight()) {// 如果图片高度小于控件高度(屏幕高度)不允许纵向移动
             dy = 0;
             isCheckTop = false;
           }
           mScaleMatrix.postTranslate(dx, dy);
           checkTranslateWithBorder();
           setImageMatrix(mScaleMatrix);
         }
       }
       mLastX = x;
       mLastY = y;
       break;
     case MotionEvent.ACTION_UP:
     case MotionEvent.ACTION_CANCEL:
       mLastPinterCount = 0;
       break;
   }
   return true;
 }
 /**
  * 移动图片时进行边界检查
  * @description:
  * @date 2016-1-8 下午4:02:24
  */
 private void checkTranslateWithBorder() {
   RectF rectf = getMatrixRectf();
   float delX = 0;
   float delY = 0;
   int width = getWidth();
   int height = getHeight();
   if (rectf.top > 0 && isCheckTop) {
     delY = -rectf.top;
   }
   if (rectf.bottom < height && isCheckTop) {
     delY = height - rectf.bottom;
   }
   if (rectf.left > 0 && isCheckLeft) {
     delX = -rectf.left;
   }
   if (rectf.right < width && isCheckLeft) {
     delX = width - rectf.right;
   }
   mScaleMatrix.postTranslate(delX, delY);
 }
 // 判断是否有移动
 private boolean isMove(float x, float y) {
   return Math.sqrt(x * x + y * y) > mTouchSlop;
 }
 /**
  * 获取图片的位置
  * @description:
  * @date 2016-1-8 上午9:02:10
  */
 private RectF getMatrixRectf() {
   Matrix matrix = mScaleMatrix;
   RectF recft = new RectF();
   if (getDrawable() != null) {
     recft.set(0, 0, getDrawable().getIntrinsicWidth(), getDrawable().getIntrinsicHeight());
     matrix.mapRect(recft);
   }
   return recft;
 }

// 获取当前图片的缩放值
 private float getScale() {
   float values[] = new float[9];
   mScaleMatrix.getValues(values);
   return values[Matrix.MSCALE_X];
 }
}
0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com