Android多点触控之ZoomImageView完全解析

ZoomImageView是一个类似photoview的图片预览控件,实现了对图片的手势放大缩小平移,以及双击放大缩小解决和viewpager滑动冲突等功能,主要是通过GestureDetector,Matrix相关api以及对事件的ontouch处理实现的,这个代码网上能搜索到很多,但是因为注释少所以要完全读懂有些困难,于是本人整理了一段时间,写了一个完整的注释版本,基本每行代码都做到了讲解,大家共同学习。

public class ZoomImageView extends ImageView implements ViewTreeObserver.OnGlobalLayoutListener,ScaleGestureDetector.OnScaleGestureListener,View.OnTouchListener{
   
    @SuppressWarnings("unused")
    private static final String TAG = "ZoomImageView";

    /**
     * 最大放大倍数
     */
    public static final float mMaxScale = 4.0f;

    /**
     * 默认缩放
     */
    private float mInitScale = 1.0f;
    /**
     * 双击放大比例
     */
    private float mMidScale=2.0f;

    /**
     * 检测缩放手势 多点触控手势识别 独立的类不是GestureDetector的子类
     */
    ScaleGestureDetector mScaleGestureDetector = null;//检测缩放的手势
    /**
     *检测类似长按啊 轻按啊 拖动 快速滑动 双击啊等等 OnTouch方法虽然也可以
     * 但是对于一些复杂的手势需求自己去通过轨迹时间等等判断很复杂,因此我们采用系统
     * 提供的手势类进行处理
     */
    private GestureDetector mGestureDetector;
    /**
     * 如果正在缩放中就不向下执行,防止多次双击
     */
    private boolean mIsAutoScaling;
    /**
     * Matrix的对图像的处理
     * Translate 平移变换
     * Rotate 旋转变换
     * Scale 缩放变换
     * Skew 错切变换
     */
    Matrix mScaleMatrix = new Matrix();

    /**
     * 处理矩阵的9个值
     */
    float[] mMartixValue = new float[9];

    public ZoomImageView(Context context) {
        this(context, null);
    }

    public ZoomImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ZoomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setScaleType(ScaleType.MATRIX);
        mScaleGestureDetector = new ScaleGestureDetector(context, this);
        this.setOnTouchListener(this); //缩放的捕获要建立在setOnTouchListener上
        //符合滑动的距离 它获得的是触发移动事件的最短距离,如果小于这个距离就不触发移动控件,
        //如viewpager就是用这个距离来判断用户是否翻页
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        //监听双击事件 SimpleOnGestureListener是OnGestureListener接口实现类,
        //使用这个复写需要的方法就可以不用复写所有的方法
        mGestureDetector = new GestureDetector(context, 
        new   GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                //如果正在缩放中就不向下执行,防止多次双击
                if (mIsAutoScaling) {
                    return true;
                }
                //缩放的中心点
                float x = e.getX();
                float y = e.getY();
                //如果当前缩放值小于这个临界值 则进行放大
                if (getScale() < mMidScale) {
                    mIsAutoScaling = true;
                    //view中的方法 已x,y为坐标点放大到mMidScale 延时10ms
                    postDelayed(new AutoScaleRunble(mMidScale, x, y), 16);
                } else {
                   //如果当前缩放值大于这个临界值 则进行缩小操作 缩小到mInitScale
                    mIsAutoScaling = true;
                    postDelayed(new AutoScaleRunble(mInitScale, x, y), 16);
                }
                return true;
            }

        });
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    //suppress deprecate warning because i have dealt with it
    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值