android自定义图片,支持缩放拖拽的功能实现

在项目中有用到对图片处理,封装了工具代码类支持左右滑动,双击放大缩小,同时也支持根据手势滑动进行对图片的放大与缩小.

androidSDK中本身对手势处理就做了封装,而我们要做的只是根据手势的触发进行对图片处理,在这个过程中需要做到对内存进行优化,防止内存溢出.好,闲话少说直接看代码


setupOnTouchListeners是对展示的View进行做触摸监听

private void setupOnTouchListeners(View rootView) {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
      mScaleGestureDetector = new ScaleGestureDetector(this,
            new MyOnScaleGestureListener());
   }
   mGestureDetector = new GestureDetector(this, new MyGestureListener());

   OnTouchListener rootListener = new OnTouchListener() {
      public boolean onTouch(View v, MotionEvent event) {
         // NOTE: gestureDetector may handle onScroll..
         if (!mOnScale) {
            if (!mOnPagerScoll) {
               mGestureDetector.onTouchEvent(event);
            }
         }

         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_MR1) {
            if (!mOnPagerScoll) {
               mScaleGestureDetector.onTouchEvent(event);
            }
         }

         ImageViewTouch imageView = getCurrentImageView();
         if (imageView == null) {
            return true;
         }
         if (!mOnScale) {
            Matrix m = imageView.getImageViewMatrix();
            RectF rect = new RectF(0, 0, imageView.mBitmapDisplayed
                  .getBitmap().getWidth(), imageView.mBitmapDisplayed
                  .getBitmap().getHeight());
            m.mapRect(rect);
            // 图片超出屏幕范围后移动
            if (!(rect.right > imageView.getWidth() + 0.1 && rect.left < -0.1)) {
               try {
                  mViewPager.onTouchEvent(event);
               } catch (ArrayIndexOutOfBoundsException e) {
                  // why?
               }
            }
         }

         return true;
      }
   };

   rootView.setOnTouchListener(rootListener);
}

自定义个手势监听的类,在这里对手势改变进行监听触发图片放大缩小的方法,改变图片
private class MyGestureListener extends
      GestureDetector.SimpleOnGestureListener {

   @Override
   public boolean onScroll(MotionEvent e1, MotionEvent e2,
         float distanceX, float distanceY) {
      // Log.d(TAG, "gesture onScroll");
      if (mOnScale) {
         return true;
      }
      if (mPaused) {
         return false;
      }
      ImageViewTouch imageView = getCurrentImageView();
      if (imageView == null) {
         return true;
      }
      imageView.panBy(-distanceX, -distanceY);
      imageView.center(true, true);

      // 超出边界效果去掉这个
      imageView.center(true, true);

      return true;
   }

   @Override
   public boolean onUp(MotionEvent e) {
      return super.onUp(e);
   }


   @Override
   public boolean onDoubleTap(MotionEvent e) {
      if (mPaused) {
         return false;
      }
      ImageViewTouch imageView = getCurrentImageView();
      if (imageView == null) {
         return true;
      }
      // Switch between the original scale and 3x scale.
      if (imageView.mBaseZoom < 1) {
         if (imageView.getScale() > 2F) {
            imageView.zoomTo(1f);
         } else {
            imageView.zoomToPoint(3f, e.getX(), e.getY());
         }
      } else {
         if (imageView.getScale() > (imageView.mMinZoom + imageView.mMaxZoom) / 2f) {
            imageView.zoomTo(imageView.mMinZoom);
         } else {
            imageView.zoomToPoint(imageView.mMaxZoom, e.getX(),
                  e.getY());
         }
      }

      return true;
   }
}

对手势缩放比例进行监听动态改变图像大小
private class MyOnScaleGestureListener extends
      ScaleGestureDetector.SimpleOnScaleGestureListener {

   float currentScale;
   float currentMiddleX;
   float currentMiddleY;

   @Override
   public void onScaleEnd(ScaleGestureDetector detector) {


      final ImageViewTouch imageView = getCurrentImageView();
      if (imageView == null) {
         return;
      }

      Log.d(TAG, "currentScale: " + currentScale + ", maxZoom: "
            + imageView.mMaxZoom);
      if (currentScale > imageView.mMaxZoom) {
         imageView
               .zoomToNoCenterWithAni(currentScale
                     / imageView.mMaxZoom, 1, currentMiddleX,
                     currentMiddleY);
         currentScale = imageView.mMaxZoom;
         imageView.zoomToNoCenterValue(currentScale, currentMiddleX,
               currentMiddleY);
      } else if (currentScale < imageView.mMinZoom) {
         imageView.zoomToNoCenterWithAni(currentScale,
               imageView.mMinZoom, currentMiddleX, currentMiddleY);
         currentScale = imageView.mMinZoom;
         imageView.zoomToNoCenterValue(currentScale, currentMiddleX,
               currentMiddleY);
      } else {
         imageView.zoomToNoCenter(currentScale, currentMiddleX,
               currentMiddleY);
      }

      imageView.center(true, true);

      // NOTE: 延迟修正缩放后可能移动问题
      imageView.postDelayed(new Runnable() {
         @Override
         public void run() {
            mOnScale = false;
         }
      }, 300);
      // Log.d(TAG, "gesture onScaleEnd");
   }

   @Override
   public boolean onScaleBegin(ScaleGestureDetector detector) {
      // Log.d(TAG, "gesture onScaleStart");
      mOnScale = true;
      return true;
   }

   @Override
   public boolean onScale(ScaleGestureDetector detector, float mx, float my) {
      // Log.d(TAG, "gesture onScale");
      ImageViewTouch imageView = getCurrentImageView();
      if (imageView == null) {
         return true;
      }
      float ns = imageView.getScale() * detector.getScaleFactor();

      currentScale = ns;
      currentMiddleX = mx;
      currentMiddleY = my;

      if (detector.isInProgress()) {
         imageView.zoomToNoCenter(ns, mx, my);
      }
      return true;
   }
}

源码下载 https://github.com/kyrieLiu/TouchImage.git



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值