美文网首页
实现自定义拖拽、放大的imageview

实现自定义拖拽、放大的imageview

作者: 阿里高级软件架构师 | 来源:发表于2020-05-20 22:32 被阅读0次

    这种控件很简单,基本上没什么难度,无非就是onTouch事件的处理:

    我们先从简单的做起,实现自定义拖拽:

    首先,你移动的过程中,你得记录一下你刚开始的位置,然后你移动完成后,需要记录一下终点,至于这个距离如何记录,onTouch正好给你API去获取移动的距离,然后学过数学的都知道,一个手机屏幕是一个二维坐标系统,你都知道了起点,知道了终点,然后你做一下加法,不就出来了。

    getImageMatrix()你先获取手机屏幕的矩阵元素,然后通过MotionEvent获取起点的坐标,如下图所示:

    然后你移动,产生距离,那距离就来搞一下下啊,你往前,就用终点减去起点,就是移动距离,你既然获得距离了,就来移动啊!

    postTranslate(),使用这个方法就可以实现移动的功能了。

            然后接下来就得实现缩小放大的功能;一般你放大是不是得两根手指头,那触摸点是不是就得有两个了,那你如何获取放大的倍数?我给你一个思路:你手指动了,你是不是会产生缩放距离,同时在X或者Y轴或者同时,那你就会有一个产生的缩放距离,在X轴和Y轴上的,你都知道了X和Y的距离了,那来一个勾股定理,是不是就得算出来了斜边的距离,因为你动手指,产生了距离,不管你移动了多少,斜边都会产生移动。那你用初始的斜边长度去除以手势在屏幕上移动后产生的斜边长度,结果就是缩放的比例大小。这个比例你获取到了,但是你是不是得有一个缩放点,就是你根据哪个点进行缩放的,我们一般取缩放后的中间点,如果你取起点,那就是反向了,取终点,就缩放不正常,会产生二倍放大,这个是线性代数里面的一个基本的知识。然后你用postScale()方法进行缩放,第一个是X轴的缩放,第二个是Y轴的缩放,然后后面两个是中点,中间点就是你两个手指的中间点。思路都出来了,代码就出来了:

    package com.ireader.plug.testapplication;

    import android.content.Context;

    import android.graphics.Matrix;

    import android.graphics.PointF;

    import android.util.AttributeSet;

    import android.view.MotionEvent;

    import android.view.View;

    import android.widget.ImageView;

    public class BaseDragZoomImageViewextends ImageViewimplements View.OnTouchListener{

      private int mode =0;

      private static final int MODE_DRAG =1;

      private static final int MODE_ZOOM =2;

      private PointFstartPoint =new PointF();

      private Matrixmatrix =new Matrix();

      private MatrixcurrentMatrix =new Matrix();

      private float startDis;

      private PointFmidPoint;

      public BaseDragZoomImageView(Context context, AttributeSet attrs, int defStyle)

    {

        super(context, attrs, defStyle);

        setOnTouchListener(this);

      }

      public BaseDragZoomImageView(Context context, AttributeSet attrs)

    {

        this(context, attrs, 0);

        setOnTouchListener(this);

      }

      public BaseDragZoomImageView(Context context)

    {

        this(context, null);

        setOnTouchListener(this);

      }

      @Override

      public boolean onTouch(View v, MotionEvent event) {

        switch (event.getAction() & MotionEvent.ACTION_MASK) {

          case MotionEvent.ACTION_DOWN:

            mode = MODE_DRAG;

            currentMatrix.set(getImageMatrix());

            startPoint.set(event.getX(), event.getY());

    break;

          // 手指在屏幕上移动,改事件会被不断触发

          case MotionEvent.ACTION_MOVE:

            if (mode == MODE_DRAG) {

              float dx = event.getX() - startPoint.x;

              float dy = event.getY() - startPoint.y;

              matrix.set(currentMatrix);

              matrix.postTranslate(dx, dy);

            }

            else if (mode == MODE_ZOOM) {

              float endDis = distance(event);

              if (endDis > 10f) {

                float scale = endDis / startDis;

                matrix.set(currentMatrix);

                matrix.postScale(scale, scale,midPoint.x,midPoint.y);

              }

    }

            break;

          case MotionEvent.ACTION_UP:

          case MotionEvent.ACTION_POINTER_UP:

            mode = 0;

    break;

          case MotionEvent.ACTION_POINTER_DOWN:

            mode = MODE_ZOOM;

            startDis = distance(event);

            if (startDis > 10f) {

              midPoint = mid(event);

              currentMatrix.set(getImageMatrix());

            }

            break;

        }

    setImageMatrix(matrix);

    return true;

      }

      private float distance(MotionEvent event) {

        float dx = event.getX(1) - event.getX(0);

        float dy = event.getY(1) - event.getY(0);

        return (float) Math.sqrt(dx * dx + dy * dy);

      }

      private PointFmid(MotionEvent event) {

        float midX =(event.getX(1) + event.getX(0)) /2;

        float midY =(event.getY(1) + event.getY(0)) /2;

        return new PointF(midX, midY);

      }

    }

    相关文章

      网友评论

          本文标题:实现自定义拖拽、放大的imageview

          本文链接:https://www.haomeiwen.com/subject/iumoohtx.html