为了账号安全,请及时绑定邮箱和手机立即绑定

OnTouchEvent+Matrix图片缩放简单实现

标签:
Android

准备

我们需要一个Activity以及对应的布局文件,当然也可以用fragment;
在布局文件中,添加一个放置图片的ImageView控件,并设置好图片和ID。
这是我的Activity和布局文件,以及设置好图片和ID的ImageView控件:


https://img1.sycdn.imooc.com/5d2c6fe30001f22505320329.jpg

图片描述

开始

在Activity中绑定控件(这里我用的butterknife快速绑定),创建三个常量,表示手指的三种状态:抬起,缩放,拖拽;创建一个变量,记录这三种状态:

    @BindView(R.id.img)
    ImageView img;    private final int NONE=0;//抬起
    private final int ZOOM=1;//缩放
    private final int DRAG=2;//拖拽
    private int status=NONE;//存储当前状态
    private double lastDis;

再创建两个PointF对象和两个Matrix对象,干什么用的,已经写在注释里面了:

   PointF midPoint=new PointF();//当两根手指放下时,记录两根手指中点坐标
    PointF startPoint=new PointF();//当一根手指放下时,记录当前坐标
    Matrix matrix=new Matrix();//用于变换图片的矩阵
    Matrix savedMatrix=new Matrix();//用于存储矩阵信息

在onCreate()方法中设置图片的缩放方式为矩阵缩放:

   img.setScaleType(ImageView.ScaleType.MATRIX);//设置图片的缩放方式

重写onTouchEvent()方法:

     /**
     * 当单指放下时,用先用matrix保存图片信息,再将matrix的值赋给savedMatrix,startPoint记录当前坐标,status记录当前状态;
     * 当双指放下时,lastDis记录两指之间的距离,将matrix当前值付给savedMatrix,midPoint记录两指的中点坐标,status记录当前状态。
     *
     * 当手指开始移动时,根据status的值决定移动还是缩放;
     * 如果是移动,将savedMatrix的值赋给matrix,调用matrix.postTranslate()方法,更改matrix的值;
     * 如果是缩放,获取当前手指之间的距离,同样将savedMatrix的值赋给matrix,调用matrix.postScale()方法更改matrix的值。
     *
     * 最后再switch语句外边,调用img.setImageMatrix()变换图片。
     * @param event
     * @return
     */

    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (MotionEvent.ACTION_MASK&event.getAction()){            case MotionEvent.ACTION_DOWN:
                matrix.set(img.getImageMatrix());
                savedMatrix.set(matrix);
                startPoint.set(event.getX(),event.getY());
                status=DRAG;                break;            case MotionEvent.ACTION_POINTER_DOWN:
                lastDis=getFingerDis(event);
                savedMatrix.set(matrix);
                midPoint=getMidPoint(event);
                status=ZOOM;                break;            case MotionEvent.ACTION_MOVE:                switch (status){                    case DRAG:
                        matrix.set(savedMatrix);
                        matrix.postTranslate(event.getX()-startPoint.x,event.getY()-startPoint.y);                        break;                    case ZOOM:                        double curDis=getFingerDis(event);                         float scaleMul= (float) (curDis/lastDis);
                        matrix.set(savedMatrix);
                        matrix.postScale(scaleMul,scaleMul,midPoint.x,midPoint.y);                        break;
                }                break;            case MotionEvent.ACTION_UP:            case MotionEvent.ACTION_POINTER_UP:
                status=NONE;                break;
        }
        img.setImageMatrix(matrix);//让图片根据矩阵信息变化(平移或缩放)
        return true;
    }

获取两点间距离的方法:

private double getFingerDis(MotionEvent e){    double disX=Math.abs(e.getX(0)-e.getX(1));    double disY=Math.abs(e.getY(0)-e.getY(1));    return Math.sqrt(disX*disX+disY*disY);
}

获取两点间中点坐标的方法:

private PointF getMidPoint(MotionEvent e){  float midX=(e.getX(0)+e.getX(1))/2;  float midY=(e.getY(0)+e.getY(1))/2;  return new PointF(midX,midY);
}



作者:Mingho96
链接:https://www.jianshu.com/p/f35b234195e0


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消