Android放大并缩小ImageView中的图像

时间:2014-07-24 04:50:31

标签: android image-zoom

正在创建一个Android测验应用程序,其中一个问题类型将是图片基础问题,如下图所示。我拍摄了四张图片视图,如图片所示,并在图片视图中显示来自服务器的图片。所以我的问题是。点击每个图像,图像必须放大,然后点击它应该缩小,任何人都可以帮助我这样做。 enter image description here

2 个答案:

答案 0 :(得分:0)

尝试使用此自定义ImageView,希望这可以帮助您解决问题。

public class GestureImageView extends ImageView {

    public static final String GLOBAL_NS = "http://schemas.android.com/apk/res/android";
    public static final String LOCAL_NS = "http://schemas.polites.com/android";

    private final Semaphore drawLock = new Semaphore(0);
    private Animator animator;

    private Drawable drawable;

    private float x = 0, y = 0;

    private boolean layout = false;

    private float scaleAdjust = 1.0f;
    private float startingScale = -1.0f;

    private float scale = 1.0f;
    private float maxScale = 5.0f;
    private float minScale = 0.75f;
    private float fitScaleHorizontal = 1.0f;
    private float fitScaleVertical = 1.0f;
    private float rotation = 0.0f;

    private float centerX;
    private float centerY;

    private Float startX, startY;

    private int hWidth;
    private int hHeight;

    private int resId = -1;
    private boolean recycle = false;
    private boolean strict = false;

    private int displayHeight;
    private int displayWidth;

    private int alpha = 255;
    private ColorFilter colorFilter;

    private int deviceOrientation = -1;
    private int imageOrientation;

    private GestureImageViewListener gestureImageViewListener;
    private GestureImageViewTouchListener gestureImageViewTouchListener;

    private OnTouchListener customOnTouchListener;
    private OnClickListener onClickListener;

    public GestureImageView(Context context, AttributeSet attrs, int defStyle) {
        this(context, attrs);
    }

    public GestureImageView(Context context, AttributeSet attrs) {
        super(context, attrs);

        String scaleType = attrs.getAttributeValue(GLOBAL_NS, "scaleType");

        if (scaleType == null || scaleType.trim().length() == 0) {
            setScaleType(ScaleType.CENTER_INSIDE);
        }

        String strStartX = attrs.getAttributeValue(LOCAL_NS, "start-x");
        String strStartY = attrs.getAttributeValue(LOCAL_NS, "start-y");

        if (strStartX != null && strStartX.trim().length() > 0) {
            startX = Float.parseFloat(strStartX);
        }

        if (strStartY != null && strStartY.trim().length() > 0) {
            startY = Float.parseFloat(strStartY);
        }

        setStartingScale(attrs.getAttributeFloatValue(LOCAL_NS, "start-scale", startingScale));
        setMinScale(attrs.getAttributeFloatValue(LOCAL_NS, "min-scale", minScale));
        setMaxScale(attrs.getAttributeFloatValue(LOCAL_NS, "max-scale", maxScale));
        setStrict(attrs.getAttributeBooleanValue(LOCAL_NS, "strict", strict));
        setRecycle(attrs.getAttributeBooleanValue(LOCAL_NS, "recycle", recycle));

        initImage();
    }

    public GestureImageView(Context context) {
        super(context);
        setScaleType(ScaleType.CENTER_INSIDE);
        initImage();
    }

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

        if (drawable != null) {
            int orientation = getResources().getConfiguration().orientation;
            if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                displayHeight = MeasureSpec.getSize(heightMeasureSpec);

                if (getLayoutParams().width == LayoutParams.WRAP_CONTENT) {
                    float ratio = (float) getImageWidth() / (float) getImageHeight();
                    displayWidth = Math.round((float) displayHeight * ratio);
                } else {
                    displayWidth = MeasureSpec.getSize(widthMeasureSpec);
                }
            } else {
                displayWidth = MeasureSpec.getSize(widthMeasureSpec);
                if (getLayoutParams().height == LayoutParams.WRAP_CONTENT) {
                    float ratio = (float) getImageHeight() / (float) getImageWidth();
                    displayHeight = Math.round((float) displayWidth * ratio);
                } else {
                    displayHeight = MeasureSpec.getSize(heightMeasureSpec);
                }
            }
        } else {
            displayHeight = MeasureSpec.getSize(heightMeasureSpec);
            displayWidth = MeasureSpec.getSize(widthMeasureSpec);
        }

        setMeasuredDimension(displayWidth, displayHeight);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed || !layout) {
            setupCanvas(displayWidth, displayHeight, getResources().getConfiguration().orientation);
        }
    }

    protected void setupCanvas(int measuredWidth, int measuredHeight, int orientation) {

        if (deviceOrientation != orientation) {
            layout = false;
            deviceOrientation = orientation;
        }

        if (drawable != null && !layout) {
            int imageWidth = getImageWidth();
            int imageHeight = getImageHeight();

            hWidth = Math.round(((float) imageWidth / 2.0f));
            hHeight = Math.round(((float) imageHeight / 2.0f));

            measuredWidth -= (getPaddingLeft() + getPaddingRight());
            measuredHeight -= (getPaddingTop() + getPaddingBottom());

            computeCropScale(imageWidth, imageHeight, measuredWidth, measuredHeight);

            if (startingScale <= 0.0f) {
                computeStartingScale(imageWidth, imageHeight, measuredWidth, measuredHeight);
            }

            scaleAdjust = startingScale;

            this.centerX = (float) measuredWidth / 2.0f;
            this.centerY = (float) measuredHeight / 2.0f;

            if (startX == null) {
                x = centerX;
            } else {
                x = startX;
            }

            if (startY == null) {
                y = centerY;
            } else {
                y = startY;
            }

            gestureImageViewTouchListener = new GestureImageViewTouchListener(this, measuredWidth, measuredHeight);

            if (isLandscape()) {
                gestureImageViewTouchListener.setMinScale(minScale * fitScaleHorizontal);
            } else {
                gestureImageViewTouchListener.setMinScale(minScale * fitScaleVertical);
            }

            gestureImageViewTouchListener.setMaxScale(maxScale * startingScale);

            gestureImageViewTouchListener.setFitScaleHorizontal(fitScaleHorizontal);
            gestureImageViewTouchListener.setFitScaleVertical(fitScaleVertical);
            gestureImageViewTouchListener.setCanvasWidth(measuredWidth);
            gestureImageViewTouchListener.setCanvasHeight(measuredHeight);
            gestureImageViewTouchListener.setOnClickListener(onClickListener);

            drawable.setBounds(-hWidth, -hHeight, hWidth, hHeight);

            super.setOnTouchListener(new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (customOnTouchListener != null) {
                        customOnTouchListener.onTouch(v, event);
                    }
                    return gestureImageViewTouchListener.onTouch(v, event);
                }
            });

            layout = true;
        }
    }

    protected void computeCropScale(int imageWidth, int imageHeight, int measuredWidth, int measuredHeight) {
        fitScaleHorizontal = (float) measuredWidth / (float) imageWidth;
        fitScaleVertical = (float) measuredHeight / (float) imageHeight;
    }

    protected void computeStartingScale(int imageWidth, int imageHeight, int measuredWidth, int measuredHeight) {
        switch (getScaleType()) {
        case CENTER:
            // Center the image in the view, but perform no scaling.
            startingScale = 1.0f;
            break;

        case CENTER_CROP:
            startingScale = Math.max((float) measuredHeight / (float) imageHeight, (float) measuredWidth / (float) imageWidth);
            break;

        case CENTER_INSIDE:
            if (isLandscape()) {
                startingScale = fitScaleHorizontal;
            } else {
                startingScale = fitScaleVertical;
            }
            break;
        default:
            break;
        }
    }

    protected boolean isRecycled() {
        if (drawable != null && drawable instanceof BitmapDrawable) {
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            if (bitmap != null) {
                return bitmap.isRecycled();
            }
        }
        return false;
    }

    protected void recycle() {
        if (recycle && drawable != null && drawable instanceof BitmapDrawable) {
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            if (bitmap != null) {
                bitmap.recycle();
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (layout) {
            if (drawable != null && !isRecycled()) {
                canvas.save();

                float adjustedScale = scale * scaleAdjust;

                canvas.translate(x, y);

                if (rotation != 0.0f) {
                    canvas.rotate(rotation);
                }

                if (adjustedScale != 1.0f) {
                    canvas.scale(adjustedScale, adjustedScale);
                }

                drawable.draw(canvas);

                canvas.restore();
            }

            if (drawLock.availablePermits() <= 0) {
                drawLock.release();
            }
        }
    }

    /**
     * Waits for a draw
     * 
     * @param max
     *            time to wait for draw (ms)
     * @throws InterruptedException
     */
    public boolean waitForDraw(long timeout) throws InterruptedException {
        return drawLock.tryAcquire(timeout, TimeUnit.MILLISECONDS);
    }

    @Override
    protected void onAttachedToWindow() {
        animator = new Animator(this, "GestureImageViewAnimator");
        animator.start();

        if (resId >= 0 && drawable == null) {
            setImageResource(resId);
        }

        super.onAttachedToWindow();
    }

    public void animationStart(Animation animation) {
        if (animator != null) {
            animator.play(animation);
        }
    }

    public void animationStop() {
        if (animator != null) {
            animator.cancel();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        if (animator != null) {
            animator.finish();
        }
        if (recycle && drawable != null && !isRecycled()) {
            recycle();
            drawable = null;
        }
        super.onDetachedFromWindow();
    }

    protected void initImage() {
        if (this.drawable != null) {
            this.drawable.setAlpha(alpha);
            this.drawable.setFilterBitmap(true);
            if (colorFilter != null) {
                this.drawable.setColorFilter(colorFilter);
            }
        }

        if (!layout) {
            requestLayout();
            redraw();
        }
    }

    public void setImageBitmap(Bitmap image) {
        this.drawable = new BitmapDrawable(getResources(), image);
        initImage();
    }

    @Override
    public void setImageDrawable(Drawable drawable) {
        this.drawable = drawable;
        initImage();
    }

    public void setImageResource(int id) {
        if (this.drawable != null) {
            this.recycle();
        }
        if (id >= 0) {
            this.resId = id;
            setImageDrawable(getContext().getResources().getDrawable(id));
        }
    }

    public int getScaledWidth() {
        return Math.round(getImageWidth() * getScale());
    }

    public int getScaledHeight() {
        return Math.round(getImageHeight() * getScale());
    }

    public int getImageWidth() {
        if (drawable != null) {
            return drawable.getIntrinsicWidth();
        }
        return 0;
    }

    public int getImageHeight() {
        if (drawable != null) {
            return drawable.getIntrinsicHeight();
        }
        return 0;
    }

    public void moveBy(float x, float y) {
        this.x += x;
        this.y += y;
    }

    public void setPosition(float x, float y) {
        this.x = x;
        this.y = y;
    }

    public void redraw() {
        postInvalidate();
    }

    public void setMinScale(float min) {
        this.minScale = min;
        if (gestureImageViewTouchListener != null) {
            gestureImageViewTouchListener.setMinScale(min * fitScaleHorizontal);
        }
    }

    public void setMaxScale(float max) {
        this.maxScale = max;
        if (gestureImageViewTouchListener != null) {
            gestureImageViewTouchListener.setMaxScale(max * startingScale);
        }
    }

    public void setScale(float scale) {
        scaleAdjust = scale;
    }

    public float getScale() {
        return scaleAdjust;
    }

    public float getImageX() {
        return x;
    }

    public float getImageY() {
        return y;
    }

    public boolean isStrict() {
        return strict;
    }

    public void setStrict(boolean strict) {
        this.strict = strict;
    }

    public boolean isRecycle() {
        return recycle;
    }

    public void setRecycle(boolean recycle) {
        this.recycle = recycle;
    }

    public void reset() {
        x = centerX;
        y = centerY;
        scaleAdjust = startingScale;
        if (gestureImageViewTouchListener != null) {
            gestureImageViewTouchListener.reset();
        }
        redraw();
    }

    public void setRotation(float rotation) {
        this.rotation = rotation;
    }

    public void setGestureImageViewListener(GestureImageViewListener pinchImageViewListener) {
        this.gestureImageViewListener = pinchImageViewListener;
    }

    public GestureImageViewListener getGestureImageViewListener() {
        return gestureImageViewListener;
    }

    @Override
    public Drawable getDrawable() {
        return drawable;
    }

    @Override
    public void setAlpha(int alpha) {
        this.alpha = alpha;
        if (drawable != null) {
            drawable.setAlpha(alpha);
        }
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        this.colorFilter = cf;
        if (drawable != null) {
            drawable.setColorFilter(cf);
        }
    }

    @Override
    public void setImageURI(Uri mUri) {
        if ("content".equals(mUri.getScheme())) {
            try {
                String[] orientationColumn = { MediaStore.Images.Media.ORIENTATION };

                Cursor cur = getContext().getContentResolver().query(mUri, orientationColumn, null, null, null);

                if (cur != null && cur.moveToFirst()) {
                    imageOrientation = cur.getInt(cur.getColumnIndex(orientationColumn[0]));
                }

                InputStream in = null;

                try {
                    in = getContext().getContentResolver().openInputStream(mUri);
                    Bitmap bmp = BitmapFactory.decodeStream(in);

                    if (imageOrientation != 0) {
                        Matrix m = new Matrix();
                        m.postRotate(imageOrientation);
                        Bitmap rotated = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);
                        bmp.recycle();
                        setImageDrawable(new BitmapDrawable(getResources(), rotated));
                    } else {
                        setImageDrawable(new BitmapDrawable(getResources(), bmp));
                    }
                } finally {
                    if (in != null) {
                        in.close();
                    }

                    if (cur != null) {
                        cur.close();
                    }
                }
            } catch (Exception e) {
                Log.w("GestureImageView", "Unable to open content: " + mUri, e);
            }
        } else {
            setImageDrawable(Drawable.createFromPath(mUri.toString()));
        }

        if (drawable == null) {
            Log.e("GestureImageView", "resolveUri failed on bad bitmap uri: " + mUri);
            // Don't try again.
            mUri = null;
        }
    }

    @Override
    public Matrix getImageMatrix() {
        if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
        return super.getImageMatrix();
    }

    @Override
    public void setScaleType(ScaleType scaleType) {
        if (scaleType == ScaleType.CENTER || scaleType == ScaleType.CENTER_CROP || scaleType == ScaleType.CENTER_INSIDE) {

            super.setScaleType(scaleType);
        } else if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
    }

    @Override
    public void invalidateDrawable(Drawable dr) {
        if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
        super.invalidateDrawable(dr);
    }

    @Override
    public int[] onCreateDrawableState(int extraSpace) {
        if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
        return super.onCreateDrawableState(extraSpace);
    }

    @Override
    public void setAdjustViewBounds(boolean adjustViewBounds) {
        if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
        super.setAdjustViewBounds(adjustViewBounds);
    }

    @Override
    public void setImageLevel(int level) {
        if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
        super.setImageLevel(level);
    }

    @Override
    public void setImageMatrix(Matrix matrix) {
        if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
    }

    @Override
    public void setImageState(int[] state, boolean merge) {
        if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
    }

    @Override
    public void setSelected(boolean selected) {
        if (strict) {
            throw new UnsupportedOperationException("Not supported");
        }
        super.setSelected(selected);
    }

    @Override
    public void setOnTouchListener(OnTouchListener l) {
        this.customOnTouchListener = l;
    }

    public float getCenterX() {
        return centerX;
    }

    public float getCenterY() {
        return centerY;
    }

    public boolean isLandscape() {
        return getImageWidth() >= getImageHeight();
    }

    public boolean isPortrait() {
        return getImageWidth() <= getImageHeight();
    }

    public void setStartingScale(float startingScale) {
        this.startingScale = startingScale;
    }

    public void setStartingPosition(float x, float y) {
        this.startX = x;
        this.startY = y;
    }

    @Override
    public void setOnClickListener(OnClickListener l) {
        this.onClickListener = l;

        if (gestureImageViewTouchListener != null) {
            gestureImageViewTouchListener.setOnClickListener(l);
        }
    }

    /**
     * Returns true if the image dimensions are aligned with the orientation of
     * the device.
     * 
     * @return
     */
    public boolean isOrientationAligned() {
        if (deviceOrientation == Configuration.ORIENTATION_LANDSCAPE) {
            return isLandscape();
        } else if (deviceOrientation == Configuration.ORIENTATION_PORTRAIT) {
            return isPortrait();
        }
        return true;
    }

    public int getDeviceOrientation() {
        return deviceOrientation;
    }
}

答案 1 :(得分:0)

你好朋友这是你的答案。

1。将Imageview添加到您的布局

<ImageView
        android:id="@+id/expanded_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="invisible" />
  1. 将以下代码添加到java文件

    imageView.setImageResource(R.drawable.sample_0);
    imageView.setTag(R.drawable.sample_0);
    imageView.setOnClickListener(new OnClickListener() {
    
        @Override
        public void onClick(View arg0) {
            int id = (Integer) arg0.getTag();
            zoomImageFromThumb(arg0, id);
        }
    });
    
  2. 将此方法添加到您的班级。

    private void zoomImageFromThumb(final View thumbView, int imageResId) {
    if (mCurrentAnimator != null) {
        mCurrentAnimator.cancel();
    }
    
    final ImageView expandedImageView = (ImageView) ((Activity) mContext) .findViewById(R.id.expanded_image);
    expandedImageView.setImageResource(imageResId);
    final Rect startBounds = new Rect();
    final Rect finalBounds = new Rect();
    final Point globalOffset = new Point();
    thumbView.getGlobalVisibleRect(startBounds);
    ((Activity) mContext).findViewById(R.id.container) .getGlobalVisibleRect(finalBounds, globalOffset);
    startBounds.offset(-globalOffset.x, -globalOffset.y);
    finalBounds.offset(-globalOffset.x, -globalOffset.y);
    float startScale;
    if ((float) finalBounds.width() / finalBounds.height() > (float) startBounds
            .width() / startBounds.height()) {
        startScale = (float) startBounds.height() / finalBounds.height();
        float startWidth = startScale * finalBounds.width();
        float deltaWidth = (startWidth - startBounds.width()) / 2;
        startBounds.left -= deltaWidth;
        startBounds.right += deltaWidth;
    } else {
        // Extend start bounds vertically
        startScale = (float) startBounds.width() / finalBounds.width();
        float startHeight = startScale * finalBounds.height();
        float deltaHeight = (startHeight - startBounds.height()) / 2;
        startBounds.top -= deltaHeight;
        startBounds.bottom += deltaHeight;
    }
    thumbView.setAlpha(0f);
    expandedImageView.setVisibility(View.VISIBLE);
    expandedImageView.setPivotX(0f);
    expandedImageView.setPivotY(0f);
    AnimatorSet set = new AnimatorSet();
    set.play(
            ObjectAnimator.ofFloat(expandedImageView, View.X,
                    startBounds.left, finalBounds.left))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
                    startBounds.top, finalBounds.top))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_X,
                    startScale, 1f))
            .with(ObjectAnimator.ofFloat(expandedImageView, View.SCALE_Y,
                    startScale, 1f));
    set.setDuration(mShortAnimationDuration);
    set.setInterpolator(new DecelerateInterpolator());
    set.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            mCurrentAnimator = null;
        }
    
        @Override
        public void onAnimationCancel(Animator animation) {
            mCurrentAnimator = null;
        }
    });
    set.start();
    mCurrentAnimator = set;
    final float startScaleFinal = startScale;
    expandedImageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (mCurrentAnimator != null) {
                mCurrentAnimator.cancel();
            }
    
            AnimatorSet set = new AnimatorSet();
            set.play(
                    ObjectAnimator.ofFloat(expandedImageView, View.X,
                            startBounds.left))
                    .with(ObjectAnimator.ofFloat(expandedImageView, View.Y,
                            startBounds.top))
                    .with(ObjectAnimator.ofFloat(expandedImageView,
                            View.SCALE_X, startScaleFinal))
                    .with(ObjectAnimator.ofFloat(expandedImageView,
                            View.SCALE_Y, startScaleFinal));
            set.setDuration(mShortAnimationDuration);
            set.setInterpolator(new DecelerateInterpolator());
            set.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    thumbView.setAlpha(1f);
                    expandedImageView.setVisibility(View.GONE);
                    mCurrentAnimator = null;
                }
    
                @Override
                public void onAnimationCancel(Animator animation) {
                    thumbView.setAlpha(1f);
                    expandedImageView.setVisibility(View.GONE);
                    mCurrentAnimator = null;
                }
            });
            set.start();
            mCurrentAnimator = set;
        }
    });
    

    }