Android 单点触控(放大、缩小、旋转、位移)

来源:互联网 发布:羊羔绒卫衣男淘宝网 编辑:程序博客网 时间:2024/05/29 04:21

移动开发中比较常见的手势操作有放大、缩小、旋转等。但是这其中大多数为两指实现的对图片操作手势。但是个别特殊情况例如对某个对话框进行手势操作,这样就需要用到单指实现操作手势了。相对于两指算法,单指要麻烦一些,特别对于数学不好的童鞋来说很难想到。因此特别写出来让大家参考一下。(虽然旋转的算法也是受了别人的启示才写出来,具体在哪里看到了忘记了)

不BB直接上代码:

public boolean onTouch(View v, MotionEvent event) {            int DEFAULT_MOVE = 10;// 手指移动小于该值认为没有移动            switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    parentX = event.getX();                    parentY = event.getY();                    mLastPoint.set(parentX, parentY);                    oldDistance4PointF = distance4PointF(mCenterPoint, mLastPoint);                    //在没有点击到view的情况下点击到了父布局                    if (!isTouch) {                        PublicViewHolder.getInstance().setTextFalse();                    }                    break;                case MotionEvent.ACTION_MOVE:                    float x = event.getX();                    float y = event.getY();                    if (!isTouch)                        break;                    mTouchPoint.set(x, y);                    if (translateMode) {                        /**                         * 判断位移                         */                        int changeX = (int) (x - mLastPoint.x);                        int changeY = (int) (y - mLastPoint.y);                        translationX += changeX;                        translationY += changeY;                        setTranslationX(translationX);                        setTranslationY(translationY);                    } else {                        /**                         * 判断放大缩小                         */                        scale();                        /**                         * 判断旋转                         */                        rotation();                    }                    oldDistance4PointF = distance4PointF(mCenterPoint, mTouchPoint);                    mLastPoint.set(x, y);                    break;                case MotionEvent.ACTION_UP:                    /**                     * 判断当位移值小于制定大小 触发编辑事件                     */                    if (Math.abs(event.getX() - parentX) < DEFAULT_MOVE && Math.abs(event.getY() - parentY) < DEFAULT_MOVE && isTouch && !isDeleteTouch) {                        editListener.onEdit();                    }                    translateMode = true;                    isTouch = false;                    break;            }            return true;        }    /**     * 两个点之间的距离     *     * @return     */    private float distance4PointF(PointF pf1, PointF pf2) {        float disX = Math.abs(pf2.x - pf1.x);        float disY = Math.abs(pf2.y - pf1.y);        return (float) Math.sqrt(disX * disX + disY * disY);    }    private void scale() {        float newDistance4PointF = distance4PointF(mCenterPoint, mTouchPoint);        float vDistance = newDistance4PointF - oldDistance4PointF;        if (vDistance > 0) {            //放大            scaleL(vDistance / oldDistance4PointF);        } else if (vDistance < 0) {            //缩小            scaleM(-vDistance / oldDistance4PointF);        }    }    public float scale = 1;    private float reScale = 1;    private void scaleL(float multiple) {        scale += multiple;        reScale -= multiple;        setScaleX(scale);        setScaleY(scale);        scaleBar(reScale);    }    private void scaleM(float multiple) {        scale -= multiple;        reScale += multiple;        if (scale <= 0.3) {            scale = 0.3f;            return;        }        setScaleX(scale);        setScaleY(scale);        scaleBar(reScale);    }    private void scaleBar(float scale) {        if (scale <= 0.5)            scale = 0.5f;        if (scale >= 1.0)            scale = 1.0f;        touchBar.setScaleX(scale);        touchBar.setScaleY(scale);        deleteBar.setScaleX(scale);        deleteBar.setScaleY(scale);        editBar.setScaleX(scale);        editBar.setScaleY(scale);    }    public float degrees = 0;    //center -> proMove的向量, 我们使用PointF来实现    PointF centerToProMove = new PointF();    //center -> curMove 的向量    PointF centerToCurMove = new PointF();    private void rotation() {        //旋转所组成三角形三边边长        float a = oldDistance4PointF;        float b = distance4PointF(mLastPoint, mTouchPoint);        float c = distance4PointF(mCenterPoint, mTouchPoint);        float cosArc = (a * a + c * c - b * b) / (2 * a * c);        float newDegree = (float) Math.toDegrees(Math.acos(cosArc));        centerToProMove.set((mLastPoint.x - mCenterPoint.x), (mLastPoint.y - mCenterPoint.y));        centerToCurMove.set((mTouchPoint.x - mCenterPoint.x), (mTouchPoint.y - mCenterPoint.y));        //向量叉乘结果, 如果结果为负数, 表示为逆时针, 结果为正数表示顺时针        float result = centerToProMove.x * centerToCurMove.y - centerToProMove.y * centerToCurMove.x;        if (result < 0) {            newDegree = -newDegree;        }        if (Float.valueOf(newDegree).isNaN())            return;        degrees += newDegree;        setRotation(degrees);    }

放大、缩小比较简单大概提一下,由于写这个的时候是判断点击到了一个touchBar之后才能进行手势操作,所以为了避免touchbar缩小太多无法被点到,对放大缩小的设置了一个极值。

阅读全文
0 0
原创粉丝点击