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

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

不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
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
要修改UVCCameraTextureView类使其支持多触控可以放大缩小旋转,需要进行以下步骤: 1. 在UVCCameraTextureView类中添加一个GestureDetector成员变量,用于处理手势事件。 2. 在构造函数中初始化GestureDetector,并设置OnGestureListener监听器。 3. 重写onTouchEvent方法,在该方法中将触摸事件交给GestureDetector处理。 4. 在OnGestureListener的onScale和onRotation方法中处理缩放和旋转操作,更新UVCCameraTextureView的缩放比例和旋转角度。 以下是修改后的UVCCameraTextureView类的示例代码: ```java public class MultiTouchUVCCameraTextureView extends UVCCameraTextureView { private GestureDetector mGestureDetector; private float mScaleFactor = 1.0f; private float mRotation = 0.0f; public MultiTouchUVCCameraTextureView(Context context, AttributeSet attrs) { super(context, attrs); mGestureDetector = new GestureDetector(context, new GestureListener()); mGestureDetector.setIsLongpressEnabled(false); } @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); return mGestureDetector.onTouchEvent(event); } private class GestureListener extends GestureDetector.SimpleOnGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { mScaleFactor *= detector.getScaleFactor(); mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f)); setScaleX(mScaleFactor); setScaleY(mScaleFactor); return true; } @Override public boolean onRotation(RotationGestureDetector detector) { mRotation -= detector.getAngle(); setRotation(mRotation); return true; } } } ``` 需要注意的是,上述代码中用到了RotationGestureDetector类,该类是一个自定义的旋转手势检测器,需要自行实现。可以参考Android官方的ScaleGestureDetector类的实现方式,自行编写一个RotationGestureDetector类。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值