如何在单个视图上的多个位图上实现拖放和放大/缩小功能?

时间:2013-06-27 12:47:11

标签: android

我正在开发一个流程如下的应用程序: -

1 :- User will pick image from app Gallery which a grid view after that draw selected image  on view as a overlay ,This View has background image as well. 

2 :- Now There are two button in above view one for background zoom and second for overlay zoom and drag(drag is not applicable in background).

3 :- If user click button zoom for background then overlay will not drag or zoom vice versa.

**Problem** My problem is that above functionality not work any one guide me
提前谢谢。我的代码如下: -

    protected void onSizeChanged(int width, int height, int oldWidth,
            int oldHeight) {
        super.onSizeChanged(width, height, oldWidth, oldHeight);
        containerWidth = width;
        containerHeight = height;
       if (imgBitmap != null) {
            int imgHeight = imgBitmap.getHeight();
            int imgWidth = imgBitmap.getWidth();
            float scale;
            int initX = 0;
            int initY = 0;
            if (defaultScale == ZoomableImage.DEFAULT_SCALE_FIT_INSIDE) {
                if (imgWidth > containerWidth) {
                    scale = (float) containerWidth / imgWidth;
                    float newHeight = imgHeight * scale;
                    initY = (containerHeight - (int) newHeight) / 2;

                    matrix.setScale(scale, scale);
                    matrix.postTranslate(0, initY);
                } else {
                    scale = (float) containerHeight / imgHeight;
                    float newWidth = imgWidth * scale;
                    initX = (containerWidth - (int) newWidth) / 2;

                    matrix.setScale(scale, scale);
                    matrix.postTranslate(initX, 0);
                }
                curX = initX;
                curY = initY;
                currentScale = scale;
                minScale = scale;
            } else {
                if (imgWidth > containerWidth) {
                    initY = (containerHeight - (int) imgHeight) / 2;
                    matrix.postTranslate(0, initY);
                } else {
                    initX = (containerWidth - (int) imgWidth) / 2;
                    matrix.postTranslate(initX, 0);
                }
                curX = initX;
                curY = initY;
                currentScale = 1.0f;
                minScale = 1.0f;
            }
            invalidate();
        }

        if (overlayBitmap != null) {

            int imgHeight = overlayBitmap.getHeight();
            int imgWidth = overlayBitmap.getWidth();

            float scale;
            int initX = 0;
            int initY = 0;

            if (overlaydefaultScale == ZoomableImage.DEFAULT_OVERLAY_SCALE_FIT_INSIDE) {
                if (imgWidth > overlaycontainerWidth) {
                    scale = (float) overlaycontainerWidth / imgWidth;
                    float newHeight = imgHeight * scale;
                    initY = (containerHeight - (int) newHeight) / 2;
                    overlaymatrix.setScale(scale, scale);
                    overlaymatrix.postTranslate(0, initY);
                } else {
                    scale = (float) overlaycontainerHeight / imgHeight;
                    float newWidth = imgWidth * scale;
                    initX = (overlaycontainerWidth - (int) newWidth) / 2;

                    overlaymatrix.setScale(scale, scale);
                    overlaymatrix.postTranslate(initX, 0);
                }
                overlaycurX = initX;
                overlaycurY = initY;
                overlaycurrentScale = scale;
                overlayminScale = scale;
            } else {
                if (imgWidth > overlaycontainerWidth) {
                    initY = (overlaycontainerHeight - (int) imgHeight) / 2;
                    overlaymatrix.postTranslate(0, initY);
                } else {
                    initX = (overlaycontainerWidth - (int) imgWidth) / 2;
                    overlaymatrix.postTranslate(initX, 0);
                }
                overlaycurX = initX;
                overlaycurY = initY;
                overlaycurrentScale = 1.0f;
                overlayminScale = 1.0f;
            }
            invalidate();
        }
    }
    private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
        Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
        Canvas canvas = new Canvas(bmOverlay);
        canvas.drawBitmap(bmp1,matrix,null);
        canvas.drawBitmap(bmp2,overlaymatrix, overlayPaint);
        return bmOverlay;
    }
    @Override
    protected void onDraw(Canvas canvas) {

        if (bitmapback != null && canvas != null && overlayBitmap != null && canvas != null) {

            Bitmap objbm = overlay(bitmapback,overlayBitmap);
            canvas.drawBitmap(objbm,0,0,null);
            //caas.drawBitmap(overlayBitmap,overlaymatrix, overlayPaint);
        }
        super.onDraw(canvas);
    }
    private void checkImageConstraints() {
        if (imgBitmap == null) {
            return;
        }
        float[] mvals = new float[9];
        matrix.getValues(mvals);
        currentScale = mvals[0];
        if (currentScale < minScale) {
            float deltaScale = minScale / currentScale;
            float px = containerWidth / 2;
            float py = containerHeight / 2;
            matrix.postScale(deltaScale, deltaScale, px, py);
            invalidate();
        }
        matrix.getValues(mvals);
        currentScale = mvals[0];
        curX = mvals[2];
        curY = mvals[5];
        int rangeLimitX = containerWidth
                - (int) (imgBitmap.getWidth() * currentScale);
        int rangeLimitY = containerHeight
                - (int) (imgBitmap.getHeight() * currentScale);
        boolean toMoveX = false;
        boolean toMoveY = false;
        if (rangeLimitX < 0) {
            if (curX > 0) {
                targetX = 0;
                toMoveX = true;
            } else if (curX < rangeLimitX) {
                targetX = rangeLimitX;
                toMoveX = true;
            }
        } else {
            targetX = rangeLimitX / 2;
            toMoveX = true;
        }

        if (rangeLimitY < 0) {
            if (curY > 0) {
                targetY = 0;
                toMoveY = true;
            } else if (curY < rangeLimitY) {
                targetY = rangeLimitY;
                toMoveY = true;
            }
        } else {
            targetY = rangeLimitY / 2;
            toMoveY = true;
        }
        if (toMoveX == true || toMoveY == true) {
            if (toMoveY == false) {
                targetY = curY;
            }
            if (toMoveX == false) {
                targetX = curX;
            }
        isAnimating = true;
        mHandler.removeCallbacks(mUpdateImagePositionTask);
            mHandler.postDelayed(mUpdateImagePositionTask, 100);
        }
    }
hecks and sets the target image x and y co-ordinates if out of bounds
    private void checkOverlayImageConstraints() {
        if (overlayBitmap == null) {
            return;
        }
        float[] mvals = new float[9];
        overlaymatrix.getValues(mvals);
        overlaycurrentScale = mvals[0];
        if (overlaycurrentScale < overlayminScale) {
            float deltaScale = overlayminScale / overlaycurrentScale;
            float px = overlaycontainerWidth / 2;
            float py = overlaycontainerHeight / 2;
            overlaymatrix.postScale(deltaScale, deltaScale, px, py);
            invalidate();
        }
        overlaymatrix.getValues(mvals);
        overlaycurrentScale = mvals[0];
        overlaycurX = mvals[2];
        overlaycurY = mvals[5];

        int rangeLimitX = overlaycontainerWidth
                - (int) (overlayBitmap.getWidth() * overlaycurrentScale);
        int rangeLimitY = overlaycontainerHeight
                - (int) (overlayBitmap.getHeight() * overlaycurrentScale);
        boolean toMoveX = false;
        boolean toMoveY = false;
        if (rangeLimitX < 0) {
            if (overlaycurX > 0) {
                overlaytargetX = 0;
                toMoveX = true;
            } else if (overlaycurX < rangeLimitX) {
                overlaytargetX = rangeLimitX;
                toMoveX = true;
            }
        } else {
            overlaytargetX = rangeLimitX / 2;
            toMoveX = true;
        }
        if (rangeLimitY < 0) {
            if (overlaycurY > 0) {
                overlaytargetY = 0;
                toMoveY = true;
            } else if (overlaycurY < rangeLimitY) {
                overlaytargetY = rangeLimitY;
                toMoveY = true;
            }
        } else {
            overlaytargetY = rangeLimitY / 2;
            toMoveY = true;
        }

        if (toMoveX == true || toMoveY == true) {
            if (toMoveY == false) {
                overlaytargetY = overlaycurY;
            }
            if (toMoveX == false) {
                overlaytargetX = overlaycurX;
            }
            isoverlayAnimating = true;
            overlaymHandler.removeCallbacks(mOverlayUpdateImagePositionTask);
            overlaymHandler.postDelayed(mOverlayUpdateImagePositionTask, 100);
        }
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (!AppConstant.isBackZom) {
                        if (gestureDetector.onTouchEvent(event)) {
                return true;
            }
            if (isAnimating == true) {
                return true;
            }
            float[] mvals = new float[9];
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                if (isAnimating == false) {
                    savedMatrix.set(matrix);
                    start.set(event.getX(), event.getY());
                    mode = DRAG;
                }
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist = spacing(event);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);
                    mode = ZOOM;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                matrix.getValues(mvals);
                curX = mvals[2];
                curY = mvals[5];
                currentScale = mvals[0];
                if (isAnimating == false) {
                    checkImageConstraints();
                }
                break;
            case MotionEvent.ACTION_MOVE:
            if (mode == DRAG && isAnimating == false) {
                    matrix.set(savedMatrix);
                    float diffX = event.getX() - start.x;
                    float diffY = event.getY() - start.y;
                    matrix.postTranslate(diffX, diffY);
                    matrix.getValues(mvals);
                    curX = mvals[2];
                    curY = mvals[5];
                    currentScale = mvals[0];
                } else if (mode == ZOOM && isAnimating == false) {
                    float newDist = spacing(event);
                    if (newDist > 10f) {
                        matrix.set(savedMatrix);
                        float scale = newDist / oldDist;
                        matrix.getValues(mvals);
                        currentScale = mvals[0];

                        if (currentScale * scale <= minScale) {
                            matrix.postScale(minScale / currentScale, minScale
                                    / currentScale, mid.x, mid.y);
                        } else if (currentScale * scale >= maxScale) {
                            matrix.postScale(maxScale / currentScale, maxScale
                                    / currentScale, mid.x, mid.y);
                        } else {
                            matrix.postScale(scale, scale, mid.x, mid.y);
                        }
                        matrix.getValues(mvals);
                        curX = mvals[2];
                        curY = mvals[5];
                        currentScale = mvals[0];
                    }
                }
                break;
            }
            invalidate();
        } else {
                if (gestureDetector.onTouchEvent(event)) {
                return true;
            }
                if (isoverlayAnimating == true) {
                return true;
            }
                float[] mvals = new float[9];
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                if (isoverlayAnimating == false) {
                    overlaysavedMatrix.set(overlaymatrix);
                    overlaystart.set(event.getX(), event.getY());
                    overlaymode = OVERLAY_DRAG;
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                overlayoldDist = spacing(event);
                if (overlayoldDist > 10f) {
                    overlaysavedMatrix.set(matrix);
                    midPoint(overlaymid, event);
                    overlaymode = OVERLAY_ZOOM;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                overlaymode = OVERLAY_NONE;

                overlaymatrix.getValues(mvals);
                overlaycurX = mvals[2];
                overlaycurY = mvals[5];
                overlaycurrentScale = mvals[0];

                if (isoverlayAnimating == false) {
                    checkOverlayImageConstraints();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (overlaymode == OVERLAY_DRAG && isoverlayAnimating == false) {
                    matrix.set(savedMatrix);
                    float diffX = event.getX() - overlaystart.x;
                    float diffY = event.getY() - overlaystart.y;

                    overlaymatrix.postTranslate(diffX, diffY);

                    overlaymatrix.getValues(mvals);
                    overlaycurX = mvals[2];
                    overlaycurY = mvals[5];
                    overlaycurrentScale = mvals[0];
                } else if (overlaymode == OVERLAY_ZOOM && isoverlayAnimating == false) {
                    float newDist = spacing(event);
                    if (newDist > 10f) {
                        overlaymatrix.set(overlaysavedMatrix);
                        float scale = newDist / overlayoldDist;
                        overlaymatrix.getValues(mvals);
                        overlaycurrentScale = mvals[0];

                        if (overlaycurrentScale * scale <= overlayminScale) {
                            overlaymatrix.postScale(overlayminScale / overlaycurrentScale, overlayminScale
                                    / overlaycurrentScale, overlaymid.x, overlaymid.y);
                        } else if (overlaycurrentScale * scale >= overlaymaxScale) {
                            overlaymatrix.postScale(overlaymaxScale / overlaycurrentScale, overlaymaxScale
                                    / overlaycurrentScale, overlaymid.x, overlaymid.y);
                        } else {
                            overlaymatrix.postScale(scale, scale, overlaymid.x, overlaymid.y);
                        }
                        overlaymatrix.getValues(mvals);
                        overlaycurX = mvals[2];
                        overlaycurY = mvals[5];
                        overlaycurrentScale = mvals[0];
                    }
                }
                break;
            }
                invalidate();
        }
        return true;
    }
    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);
    }
    public void setImageBitmap(Bitmap b) {
        if (b != null) {
            imgBitmap = b;

            containerWidth = getWidth();
            containerHeight = getHeight();

            int imgHeight = imgBitmap.getHeight();
            int imgWidth = imgBitmap.getWidth();

            float scale;
            int initX = 0;
            int initY = 0;
            matrix.reset();
            if (defaultScale == ZoomableImage.DEFAULT_SCALE_FIT_INSIDE) {
                if (imgWidth > containerWidth) {
                    scale = (float) containerWidth / imgWidth;
                    float newHeight = imgHeight * scale;
                    initY = (containerHeight - (int) newHeight) / 2;
                    matrix.setScale(scale, scale);
                    matrix.postTranslate(0, initY);
                } else {
                    scale = (float) containerHeight / imgHeight;
                    float newWidth = imgWidth * scale;
                    initX = (containerWidth - (int) newWidth) / 2;

                    matrix.setScale(scale, scale);
                    matrix.postTranslate(initX, 0);
                }

                curX = initX;
                curY = initY;

                currentScale = scale;
                minScale = scale;
            } else {
                if (imgWidth > containerWidth) {
                    initX = 0;
                    if (imgHeight > containerHeight) {
                        initY = 0;
                    } else {
                        initY = (containerHeight - (int) imgHeight) / 2;
                    }
                    matrix.postTranslate(0, initY);
                } else {
                    initX = (containerWidth - (int) imgWidth) / 2;
                    if (imgHeight > containerHeight) {
                        initY = 0;
                    } else {
                        initY = (containerHeight - (int) imgHeight) / 2;
                    }
                    matrix.postTranslate(initX, 0);
                }

                curX = initX;
                curY = initY;

                currentScale = 1.0f;
                minScale = 1.0f;
            }
            invalidate();
        } else {
            Log.d(TAG, "bitmap is null");
        }
    }
    public void setOverlayImageBitmap(Bitmap b) {
        if (b != null) {
            overlayBitmap = b;
            overlaycontainerWidth = getWidth();
            overlaycontainerHeight = getHeight();
            int imgHeight = overlayBitmap.getHeight();
            int imgWidth = overlayBitmap.getWidth();
            float scale;
            int initX = 0;
            int initY = 0;
            overlaymatrix.reset();
            if (overlaydefaultScale == ZoomableImage.DEFAULT_OVERLAY_SCALE_FIT_INSIDE) {
                if (imgWidth > overlaycontainerWidth) {
                    scale = (float) overlaycontainerWidth / imgWidth;
                    float newHeight = imgHeight * scale;
                    initY = (overlaycontainerHeight - (int) newHeight) / 2;
                    overlaymatrix.setScale(scale, scale);
                    overlaymatrix.postTranslate(0, initY);
                } else {
                    scale = (float) overlaycontainerHeight / imgHeight;
                    float newWidth = imgWidth * scale;
                    initX = (overlaycontainerWidth - (int) newWidth) / 2;

                    overlaymatrix.setScale(scale, scale);
                    overlaymatrix.postTranslate(initX, 0);
                }
                overlaycurX = initX;
                overlaycurY = initY;
                overlaycurrentScale = scale;
                overlayminScale = scale;
            } else {
                if (imgWidth > overlaycontainerWidth) {
                    initX = 0;
                    if (imgHeight > overlaycontainerHeight) {
                        initY = 0;
                    } else {
                        initY = (overlaycontainerHeight - (int) imgHeight) / 2;
                    }
                    overlaymatrix.postTranslate(0, initY);
                } else {
                    initX = (overlaycontainerWidth - (int) imgWidth) / 2;
                    if (imgHeight > overlaycontainerHeight) {
                        initY = 0;
                    } else {
                        initY = (overlaycontainerHeight - (int) imgHeight) / 2;
                    }
                    overlaymatrix.postTranslate(initX, 0);
                }
                overlaycurX = initX;
                overlaycurY = initY;

                overlaycurrentScale = 1.0f;
                overlayminScale = 1.0f;
            }
            invalidate();
        } else {
            Log.d(TAG, "bitmap is null");
        }
    }
        private Runnable mUpdateImagePositionTask = new Runnable() {
        public void run() {
            float[] mvals;
            if (Math.abs(targetX - curX) < 5 && Math.abs(targetY - curY) < 5) {
                isAnimating = false;
                mHandler.removeCallbacks(mUpdateImagePositionTask);
                mvals = new float[9];
                matrix.getValues(mvals);
                currentScale = mvals[0];
                curX = mvals[2];
                curY = mvals[5];
                    float diffX = (targetX - curX);
                float diffY = (targetY - curY);
                matrix.postTranslate(diffX, diffY);
            } else {
                isAnimating = true;
                mvals = new float[9];
                matrix.getValues(mvals);

                currentScale = mvals[0];
                curX = mvals[2];
                curY = mvals[5];
                float diffX = (targetX - curX) * 0.3f;
                float diffY = (targetY - curY) * 0.3f;
                matrix.postTranslate(diffX, diffY);
                mHandler.postDelayed(this, 25);
            }
            invalidate();
        }
    };
    private Runnable mOverlayUpdateImagePositionTask = new Runnable() {
        public void run() {
            float[] mvals;
            if (Math.abs(overlaytargetX - overlaycurX) < 5 && Math.abs(overlaytargetY - overlaycurY) < 5) {
                isoverlayAnimating = false;
                overlaymHandler.removeCallbacks(mOverlayUpdateImagePositionTask);
                mvals = new float[9];
                overlaymatrix.getValues(mvals);
                overlaycurrentScale = mvals[0];
                overlaycurX = mvals[2];
                overlaycurY = mvals[5];
                float diffX = (overlaytargetX - overlaycurX);
                float diffY = (overlaytargetY - overlaycurY);
                overlaymatrix.postTranslate(diffX, diffY);
            } else {
                isoverlayAnimating = true;
                mvals = new float[9];
                overlaymatrix.getValues(mvals);
                overlaycurrentScale = mvals[0];
                overlaycurX = mvals[2];
                overlaycurY = mvals[5];
                float diffX = (overlaytargetX - overlaycurX) * 0.3f;
                float diffY = (overlaytargetY - overlaycurY) * 0.3f;
                overlaymatrix.postTranslate(diffX, diffY);
                overlaymHandler.postDelayed(this, 25);
            }
            invalidate();
        }
    };
    **Here are 2 function of gesture but write only 1 due charactre ***

    private Runnable mUpdateImageScale = new Runnable() {
        public void run() {
            float transitionalRatio = targetScale / currentScale;
            float dx;
            if (Math.abs(transitionalRatio - 1) > 0.05) {
                isAnimating = true;
                if (targetScale > currentScale) {
                    dx = transitionalRatio - 1;
                    scaleChange = 1 + dx * 0.2f;
                    currentScale *= scaleChange;
                    if (currentScale > targetScale) {
                        currentScale = currentScale / scaleChange;
                        scaleChange = 1;
                    }
                } else {
                    dx = 1 - transitionalRatio;
                    scaleChange = 1 - dx * 0.5f;
                    currentScale *= scaleChange;

                    if (currentScale < targetScale) {
                        currentScale = currentScale / scaleChange;
                        scaleChange = 1;
                    }
                }
                if (scaleChange != 1) {
                    matrix.postScale(scaleChange, scaleChange, targetScaleX,
                            targetScaleY);
                    mHandler.postDelayed(mUpdateImageScale, 15);
                    invalidate();
                } else {
                    isAnimating = false;
                    scaleChange = 1;
                    matrix.postScale(targetScale / currentScale, targetScale
                            / currentScale, targetScaleX, targetScaleY);
                    currentScale = targetScale;
                    mHandler.removeCallbacks(mUpdateImageScale);
                    invalidate();
                    checkImageConstraints();
                }
            } else {
                isAnimating = false;
                scaleChange = 1;
                matrix.postScale(targetScale / currentScale, targetScale
                        / currentScale, targetScaleX, targetScaleY);
                currentScale = targetScale;
                mHandler.removeCallbacks(mUpdateImageScale);
                invalidate();
                checkImageConstraints();
            }
        }
    };
    private void dumpEvent(MotionEvent event) {
        String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
                "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
        StringBuilder sb = new StringBuilder();
        int action = event.getAction();
        int actionCode = action & MotionEvent.ACTION_MASK;
        sb.append("event ACTION_").append(names[actionCode]);
        if (actionCode == MotionEvent.ACTION_POINTER_DOWN
                || actionCode == MotionEvent.ACTION_POINTER_UP) {
            sb.append("(pid ").append(
                    action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
            sb.append(")");
        }
        sb.append("[");

        for (int i = 0; i < event.getPointerCount(); i++) {
            sb.append("#").append(i);
            sb.append("(pid ").append(event.getPointerId(i));
            sb.append(")=").append((int) event.getX(i));
            sb.append(",").append((int) event.getY(i));
            if (i + 1 < event.getPointerCount())
                sb.append(";");
        }
        sb.append("]");
    }

    **Here are 2 function of gesture but write only 1 due charactre ***
class GestureOverlayDetector extends SimpleOnGestureListener {
        @Override
        public boolean onDoubleTap(MotionEvent event) {
            if (isoverlayAnimating == true) {
                return true;
            }
            overlayscaleChange = 1;
            isoverlayAnimating = true;
            overlaytargetScaleX = event.getX();
            overlaytargetScaleY = event.getY();
            if (Math.abs(overlaycurrentScale - overlaymaxScale) > 0.1) {
                overlaytargetScale = overlaymaxScale;
            } else {
                overlaytargetScale = overlayminScale;
            }
            overlaytargetRatio = overlaytargetScale / overlaycurrentScale;
            overlaymHandler.removeCallbacks(moverlayUpdateImageScale);
            overlaymHandler.post(moverlayUpdateImageScale);
            return true;
        }
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            return super.onFling(e1, e2, velocityX, velocityY);
        }
        @Override
        public boolean onDown(MotionEvent e) {
            return false;
        }
    }   
}

在这里,我编写了我的代码,其中没有位图1是背景,其他是叠加,而不是同时绘制。也拖动不处理请任何人看到这个代码,我错了。

0 个答案:

没有答案