android - 如何在android中检测单指触摸和两指触摸?

标签 android rotation translation pinchzoom

我正在创建一个 android 应用程序,我正在缩放 ImageView [捏缩放(带有图像转换)],而且我还必须用两个手指移动来旋转 ImageView只要。因为我想通过单指移动来翻译图像 [滚动]。当我没有添加旋转代码时,捏缩放和平移工作得很好,但是在添加旋转编码图像后,单指移动时图像会旋转并且不会平移。我想检查一下,每当用户在 ImageView 上移动两根手指时,Image 应该旋转,否则不会旋转,这样 Image 翻译就不会受到干扰.如何实现? 这是我的代码。任何帮助将不胜感激

public class CustomizedImageView extends ImageView {
Matrix matrix;
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;

int mode = NONE;

// Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 3f;
float[] m;
int viewWidth, viewHeight;

static final int CLICK = 3;

float saveScale = 1f;

protected float origWidth, origHeight;

int oldMeasuredWidth, oldMeasuredHeight;

ScaleGestureDetector mScaleDetector;

Context context;
float viewRotation;
double fingerRotation;
double newFingerRotation;

public CustomizedImageView(Context context) {
    super(context);
    sharedConstructing(context);
}

public CustomizedImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    sharedConstructing(context);
}

private void sharedConstructing(Context context) {

    super.setClickable(true);

    this.context = context;

    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());

    matrix = new Matrix();

    m = new float[9];

    setImageMatrix(matrix);

    setScaleType(ScaleType.MATRIX);

    setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {

            mScaleDetector.onTouchEvent(event);

            PointF curr = new PointF(event.getX(), event.getY());
            final float x = event.getX();
            final float y = event.getY();
            final float new_x = getWidth() / 2;
            final float new_y = getHeight() / 2;

            switch (event.getAction()) {

                case MotionEvent.ACTION_DOWN:
                    //Follwing Statements are to TRANSLATE(SCROLL) IMAGE
                    //*************************************************************************
                    last.set(curr);

                    start.set(last);

                    mode = DRAG;
                    //*************************************************************************
                    //Follwing Statements are to ROTATE IMAGE With Finger Movement
                    viewRotation = getRotation();
                    fingerRotation = Math.toDegrees(Math.atan2(x - new_x, new_y - y));
                    //*************************************************************************


                    break;

                case MotionEvent.ACTION_MOVE:
                    //Follwing Statements are to TRANSLATE(SCROLL) IMAGE
                    //*************************************************************************

                    if (mode == DRAG) {

                        float deltaX = curr.x - last.x;

                        float deltaY = curr.y - last.y;

                        float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);

                        float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);

                        matrix.postTranslate(fixTransX, fixTransY);

                        fixTrans();

                        last.set(curr.x, curr.y);
                        //**********************************************************************
                        //Follwing Statements are to ROTATE IMAGE With Finger Movement
                        newFingerRotation = Math.toDegrees(Math.atan2(x - new_x, new_y - y));
                        setRotation((float) (viewRotation + newFingerRotation - fingerRotation));
                        //*************************************************************************




                    }

                    break;

                case MotionEvent.ACTION_UP:
                    //Follwing Statements are to TRANSLATE(SCROLL) IMAGE
                    //*************************************************************************
                    mode = NONE;

                    int xDiff = (int) Math.abs(curr.x - start.x);

                    int yDiff = (int) Math.abs(curr.y - start.y);

                    if (xDiff < CLICK && yDiff < CLICK)

                        performClick();
                    //*************************************************************************
                    //Follwing Statements are to ROTATE IMAGE With Finger Movement
                    fingerRotation = newFingerRotation = 0.0f;
                    //*************************************************************************


                    break;

                case MotionEvent.ACTION_POINTER_UP:
                    //Follwing Statements are to TRANSLATE(SCROLL) IMAGE
                    //*************************************************************************
                    mode = NONE;
                    //*************************************************************************

                    break;

            }

            setImageMatrix(matrix);

            invalidate();

            return true; // indicate event was handled

        }

    });
}
public void setMaxZoom(float x) {

    maxScale = x;

}

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {

        mode = ZOOM;

        return true;

    }

    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        float mScaleFactor = detector.getScaleFactor();

        float origScale = saveScale;

        saveScale *= mScaleFactor;

        if (saveScale > maxScale) {

            saveScale = maxScale;

            mScaleFactor = maxScale / origScale;

        } else if (saveScale < minScale) {

            saveScale = minScale;

            mScaleFactor = minScale / origScale;

        }

        if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight)

            matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2, viewHeight / 2);

        else

            matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());

        fixTrans();

        return true;

    }

}

void fixTrans() {

    matrix.getValues(m);

    float transX = m[Matrix.MTRANS_X];

    float transY = m[Matrix.MTRANS_Y];

    float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);

    float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale);

    if (fixTransX != 0 || fixTransY != 0)

        matrix.postTranslate(fixTransX, fixTransY);

}


float getFixTrans(float trans, float viewSize, float contentSize) {

    float minTrans, maxTrans;

    if (contentSize <= viewSize) {

        minTrans = 0;

        maxTrans = viewSize - contentSize;

    } else {

        minTrans = viewSize - contentSize;

        maxTrans = 0;

    }

    if (trans < minTrans)

        return -trans + minTrans;

    if (trans > maxTrans)

        return -trans + maxTrans;

    return 0;

}

float getFixDragTrans(float delta, float viewSize, float contentSize) {

    if (contentSize <= viewSize) {

        return 0;

    }

    return delta;

}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    viewWidth = MeasureSpec.getSize(widthMeasureSpec);

    viewHeight = MeasureSpec.getSize(heightMeasureSpec);

    //
    // Rescales image on rotation
    //
    if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight

            || viewWidth == 0 || viewHeight == 0)

        return;

    oldMeasuredHeight = viewHeight;

    oldMeasuredWidth = viewWidth;

    if (saveScale == 1) {

        //Fit to screen.

        float scale;

        Drawable drawable = getDrawable();

        if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)

            return;

        int bmWidth = drawable.getIntrinsicWidth();

        int bmHeight = drawable.getIntrinsicHeight();

        Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);

        float scaleX = (float) viewWidth / (float) bmWidth;

        float scaleY = (float) viewHeight / (float) bmHeight;

        scale = Math.min(scaleX, scaleY);

        matrix.setScale(scale, scale);

        // Center the image

        float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);

        float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);

        redundantYSpace /= (float) 2;

        redundantXSpace /= (float) 2;

        matrix.postTranslate(redundantXSpace, redundantYSpace);

        origWidth = viewWidth - 2 * redundantXSpace;

        origHeight = viewHeight - 2 * redundantYSpace;

        setImageMatrix(matrix);

    }

    fixTrans();

}

最佳答案

MotionEvent 参数具有每个事件的“指针”(即手指)的数量。

所以 MotionEvent.getPointerCount() 是你的 friend 。

https://developer.android.com/reference/android/view/MotionEvent.html#getPointerCount

关于android - 如何在android中检测单指触摸和两指触摸?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40122856/

相关文章:

android - 基于 WebView 的应用程序的纵向模式问题

swift - CAShapeLayer。旋转框架坐标更新后,但路径坐标没有更新

iphone - 将 UIImage 或 UIView 旋转到特定角度,而不是角度量

localization - 显示语言选择的最佳方式是什么?

python - Django翻译和py2exe

PHP bing api html内容翻译响应显示为纯文本

java - 我的程序不允许我调用不同类的方法

android - 使用 PagerSnapHelper 的垂直和水平 RecyclerView

java - 方法无效

ios - CABasicAnimation 如何获取当前的旋转角度