Android ImageView Scaling and translating issue

后端 未结 3 598
一向
一向 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:25

    this is a working example of two fingers move/scale/rotate (note: the code is quite short due to smart detector used - see MatrixGestureDetector):

    class ViewPort extends View {
        List layers = new LinkedList();
        int[] ids = {R.drawable.layer0, R.drawable.layer1, R.drawable.layer2};
    
        public ViewPort(Context context) {
            super(context);
            Resources res = getResources();
            for (int i = 0; i < ids.length; i++) {
                Layer l = new Layer(context, this, BitmapFactory.decodeResource(res, ids[i]));
                layers.add(l);
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            for (Layer l : layers) {
                l.draw(canvas);
            }
        }
    
        private Layer target;
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                target = null;
                for (int i = layers.size() - 1; i >= 0; i--) {
                    Layer l = layers.get(i);
                    if (l.contains(event)) {
                        target = l;
                        layers.remove(l);
                        layers.add(l);
                        invalidate();
                        break;
                    }
                }
            }
            if (target == null) {
                return false;
            }
            return target.onTouchEvent(event);
        }
    }
    
    class Layer implements MatrixGestureDetector.OnMatrixChangeListener {
        Matrix matrix = new Matrix();
        Matrix inverse = new Matrix();
        RectF bounds;
        View parent;
        Bitmap bitmap;
        MatrixGestureDetector mgd = new MatrixGestureDetector(matrix, this);
    
        public Layer(Context ctx, View p, Bitmap b) {
            parent = p;
            bitmap = b;
            bounds = new RectF(0, 0, b.getWidth(), b.getHeight());
            matrix.postTranslate(50 + (float) Math.random() * 50, 50 + (float) Math.random() * 50);
        }
    
        public boolean contains(MotionEvent event) {
            matrix.invert(inverse);
            float[] pts = {event.getX(), event.getY()};
            inverse.mapPoints(pts);
            if (!bounds.contains(pts[0], pts[1])) {
                return false;
            }
            return Color.alpha(bitmap.getPixel((int) pts[0], (int) pts[1])) != 0;
        }
    
        public boolean onTouchEvent(MotionEvent event) {
            mgd.onTouchEvent(event);
            return true;
        }
    
        @Override
        public void onChange(Matrix matrix) {
            parent.invalidate();
        }
    
        public void draw(Canvas canvas) {
            canvas.drawBitmap(bitmap, matrix, null);
        }
    }
    
    class MatrixGestureDetector {
        private static final String TAG = "MatrixGestureDetector";
    
        private int ptpIdx = 0;
        private Matrix mTempMatrix = new Matrix();
        private Matrix mMatrix;
        private OnMatrixChangeListener mListener;
        private float[] mSrc = new float[4];
        private float[] mDst = new float[4];
        private int mCount;
    
        interface OnMatrixChangeListener {
            void onChange(Matrix matrix);
        }
    
        public MatrixGestureDetector(Matrix matrix, MatrixGestureDetector.OnMatrixChangeListener listener) {
            this.mMatrix = matrix;
            this.mListener = listener;
        }
    
        public void onTouchEvent(MotionEvent event) {
            if (event.getPointerCount() > 2) {
                return;
            }
    
            int action = event.getActionMasked();
            int index = event.getActionIndex();
    
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_POINTER_DOWN:
                    int idx = index * 2;
                    mSrc[idx] = event.getX(index);
                    mSrc[idx + 1] = event.getY(index);
                    mCount++;
                    ptpIdx = 0;
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    for (int i = 0; i < mCount; i++) {
                        idx = ptpIdx + i * 2;
                        mDst[idx] = event.getX(i);
                        mDst[idx + 1] = event.getY(i);
                    }
                    mTempMatrix.setPolyToPoly(mSrc, ptpIdx, mDst, ptpIdx, mCount);
                    mMatrix.postConcat(mTempMatrix);
                    if(mListener != null) {
                        mListener.onChange(mMatrix);
                    }
                    System.arraycopy(mDst, 0, mSrc, 0, mDst.length);
                    break;
    
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_POINTER_UP:
                    if (event.getPointerId(index) == 0) ptpIdx = 2;
                    mCount--;
                    break;
            }
        }
    }
    

提交回复
热议问题