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

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

本文实例介绍了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];
 }
}
标签:Android,ImageView,图片放大,图片缩小
0
投稿

猜你喜欢

  • java实现学籍管理系统

    2023-04-03 00:32:19
  • 详解Java如何在Array和List之间进行转换

    2023-05-27 07:37:27
  • Unity实现场景加载功能

    2021-09-15 12:27:45
  • Token登陆验证机制的原理及实现

    2022-07-08 03:28:19
  • Spring Boot用户注册验证的实现全过程记录

    2023-01-03 01:58:34
  • C# 解决datagridview控件显示大量数据拖拉卡顿问题

    2022-03-21 12:52:24
  • mybatis-plus的批量新增/批量更新以及问题

    2022-10-28 04:44:16
  • java 中Map详解及实例代码

    2023-06-06 01:27:37
  • C#线程同步的几种方法总结

    2022-01-31 19:49:06
  • SpringBoot+SpringCache实现两级缓存(Redis+Caffeine)

    2023-10-02 05:20:58
  • Java 中 hashCode() 与 equals() 的关系(面试)

    2023-08-29 18:03:57
  • jdk线程池的实现

    2023-07-05 18:44:35
  • idea推送项目到gitee中的创建方法

    2021-08-19 11:27:14
  • MultipartFile中transferTo(File file)的路径问题及解决

    2023-11-12 00:07:08
  • 基于Spring Mvc实现的Excel文件上传下载示例

    2022-01-22 02:02:56
  • C#正则表达式分解和转换IP地址实例(C#正则表达式大全 c#正则表达式语法)

    2023-07-17 07:11:25
  • Servlet 过滤器详细介绍

    2021-10-21 13:51:57
  • Android实现多点触控功能

    2021-10-18 08:39:33
  • 如何将Object类转换为实体类

    2021-11-05 04:45:11
  • java数据结构与算法数组模拟队列示例详解

    2021-07-23 16:50:24
  • asp之家 软件编程 m.aspxhome.com