Android ImageView Scaling and translating issue

后端 未结 3 597
一向
一向 2020-11-21 23:35

I’m developing an android application (API 19 4.4) and I encounter some issue with ImageViews. I have a SurfaceView, in which I dynamically add ImageViews which I want to re

3条回答
  •  走了就别回头了
    2020-11-22 00:28

    I tried to implementation of multiple touch on view not on bitmap using matrix, now i success. Now i think it will helpful to you for individual gesture for multiple image. Try it, it work best for me.

    public class MultiTouchImageView extends ImageView implements OnTouchListener{
    
    float[] lastEvent = null;
    float d = 0f;
    float newRot = 0f;
    public static String fileNAME;
    public static int framePos = 0;
    //private ImageView view;
    private boolean isZoomAndRotate;
    private boolean isOutSide;
    // We can be in one of these 3 states
    private static final int NONE = 0;
    private static final int DRAG = 1;
    private static final int ZOOM = 2;
    private int mode = NONE;
    
    private PointF start = new PointF();
    private PointF mid = new PointF();
    float oldDist = 1f;
    public MultiTouchImageView(Context context) {
        super(context);
    }
    
    
    public MultiTouchImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    
    public MultiTouchImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    
    @SuppressWarnings("deprecation")
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        //view = (ImageView) v;
        bringToFront();
        // Handle touch events here...
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            //savedMatrix.set(matrix);
            start.set(event.getX(), event.getY());
            mode = DRAG;
            lastEvent = null;
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            oldDist = spacing(event);
            if (oldDist > 10f) {
                midPoint(mid, event);
                mode = ZOOM;
            }
    
            lastEvent = new float[4];
            lastEvent[0] = event.getX(0);
            lastEvent[1] = event.getX(1);
            lastEvent[2] = event.getY(0);
            lastEvent[3] = event.getY(1);
            d =  rotation(event);
            break;
        case MotionEvent.ACTION_UP:
            isZoomAndRotate = false;
        case MotionEvent.ACTION_OUTSIDE:
            isOutSide = true;
            mode = NONE;
            lastEvent = null;
        case MotionEvent.ACTION_POINTER_UP:
            mode = NONE;
            lastEvent = null;
            break;
        case MotionEvent.ACTION_MOVE:
            if(!isOutSide){
                if (mode == DRAG && !isZoomAndRotate) {
                    isZoomAndRotate = false;
                    setTranslationX((event.getX() - start.x) + getTranslationX());
                    setTranslationY((event.getY() - start.y) + getTranslationY());
                } else if (mode == ZOOM && event.getPointerCount() == 2) {
                    isZoomAndRotate = true;
                    boolean isZoom = false;
                    if(!isRotate(event)){
                        float newDist = spacing(event);
                        if (newDist > 10f) {
                            float scale = newDist / oldDist * getScaleX();
                            setScaleX(scale);
                            setScaleY(scale);
                            isZoom = true;
                        }
                    }
                    else if(!isZoom){
                        newRot = rotation(event);
                        setRotation((float)(getRotation() + (newRot - d)));
                    }
                }
            }
    
            break;
        }
        new GestureDetector(new MyGestureDectore());
        Constants.currentSticker = this;
        return true;
    }
    private class MyGestureDectore extends GestureDetector.SimpleOnGestureListener{
    
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            bringToFront();
            return false;
        }
    
        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
            return false;
        }
    
    }
    private float rotation(MotionEvent event) {
        double delta_x = (event.getX(0) - event.getX(1));
        double delta_y = (event.getY(0) - event.getY(1));
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }
    
    private void midPoint(PointF point, MotionEvent event) {
        float x = event.getX(0) + event.getX(1);
        float y = event.getY(0) + event.getY(1);
        point.set(x / 2, y / 2);
    }
    
    private boolean isRotate(MotionEvent event){
        int dx1 = (int) (event.getX(0) - lastEvent[0]);
        int dy1 = (int) (event.getY(0) - lastEvent[2]);
        int dx2 = (int) (event.getX(1) - lastEvent[1]);
        int dy2 = (int) (event.getY(1) - lastEvent[3]);
        Log.d("dx1 ", ""+ dx1);
        Log.d("dx2 ", "" + dx2);
        Log.d("dy1 ", "" + dy1);
        Log.d("dy2 ", "" + dy2);
        //pointer 1
        if(Math.abs(dx1) > Math.abs(dy1) && Math.abs(dx2) > Math.abs(dy2)) {
            if(dx1 >= 2.0 && dx2 <=  -2.0){
                Log.d("first pointer ", "right");
                return true;
            }
            else if(dx1 <= -2.0 && dx2 >= 2.0){
                Log.d("first pointer ", "left");
                return true;
            }
        }
        else {
             if(dy1 >= 2.0 && dy2 <=  -2.0){
                    Log.d("seccond pointer ", "top");
                    return true;
                }
                else if(dy1 <= -2.0 && dy2 >= 2.0){
                    Log.d("second pointer ", "bottom");
                    return true; 
                }
    
        }
    
        return false;
    }
    }
    

提交回复
热议问题