Change the size of ImageView on zooming

Android Developer picture Android Developer · Nov 28, 2014 · Viewed 11.6k times · Source

I am using chrisbanes PhotoView to implement pinch zoom..Image zooms on pinching and double tapping but i can't see that my image streched to full screen on zooming..on zooming it looks that image zooms inside a box and part of image disappears on zooming...How can i implement image zoom so that height of Image increases on zooming?I am using NetworkImageView ( of Volley library).

NetworkImageView imageView;
 PhotoViewAttacher mAttacher;

                imageView = (NetworkImageView) mImgPagerView.findViewById(R.id.imageitem);

                mAttacher = new PhotoViewAttacher(imageView);

NetworkImageView.java ( of Volley library)

     import android.content.Context;
        import android.graphics.Bitmap;
        import android.text.TextUtils;
        import android.util.AttributeSet;
        import android.widget.ImageView;
        import com.android.volley.toolbox.ImageLoader.ImageContainer;

public class NetwrokImageView extends ImageView {
    /** The URL of the network image to load */
    private String mUrl;
    /**
     * Resource ID of the image to be used as a placeholder until the network image is loaded.
     */
    private int mDefaultImageId;
    /**
     * Resource ID of the image to be used if the network response fails.
     */
    private int mErrorImageId;
    /** Local copy of the ImageLoader. */
    private ImageLoader mImageLoader;
    public NetworkImageView(Context context) {
        this(context, null);
    }
    public NetworkImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public NetworkImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    /**
     * Sets URL of the image that should be loaded into this view. Note that calling this will
     * immediately either set the cached image (if available) or the default image specified by
     * {@link NetworkImageView#setDefaultImageResId(int)} on the view.
     *
     * NOTE: If applicable, {@link NetworkImageView#setDefaultImageResId(int)} and
     * {@link NetworkImageView#setErrorImageResId(int)} should be called prior to calling
     * this function.
     *
     * @param url The URL that should be loaded into this ImageView.
     * @param imageLoader ImageLoader that will be used to make the request.
     */
    public void setImageUrl(String url, ImageLoader imageLoader) {
        mUrl = url;
        mImageLoader = imageLoader;
// The URL has potentially changed. See if we need to load it.
        loadImageIfNecessary();
    }
    /**
     * Sets the default image resource ID to be used for this view until the attempt to load it
     * completes.
     */
    public void setDefaultImageResId(int defaultImage) {
        mDefaultImageId = defaultImage;
    }
    /**
     * Sets the error image resource ID to be used for this view in the event that the image
     * requested fails to load.
     */
    public void setErrorImageResId(int errorImage) {
        mErrorImageId = errorImage;
    }
    /**
     * Loads the image for the view if it isn't already loaded.
     */
    private void loadImageIfNecessary() {
        int width = getWidth();
        int height = getHeight();
// if the view's bounds aren't known yet, hold off on loading the image.
        if (width == 0 && height == 0) {
            return;
        }
// if the URL to be loaded in this view is empty, cancel any old requests and clear the
// currently loaded image.
        if (TextUtils.isEmpty(mUrl)) {
            ImageContainer oldContainer = (ImageContainer) getTag();
            if (oldContainer != null) {
                oldContainer.cancelRequest();
                setImageBitmap(null);
            }
            return;
        }
        ImageContainer oldContainer = (ImageContainer) getTag();
// if there was an old request in this view, check if it needs to be canceled.
        if (oldContainer != null && oldContainer.getRequestUrl() != null) {
            if (oldContainer.getRequestUrl().equals(mUrl)) {
// if the request is from the same URL, return.
                return;
            } else {
// if there is a pre-existing request, cancel it if it's fetching a different URL.
                oldContainer.cancelRequest();
                setImageBitmap(null);
            }
        }
// The pre-existing content of this view didn't match the current URL. Load the new image
// from the network.
        ImageContainer newContainer = mImageLoader.get(mUrl,
                ImageLoader.getImageListener(this, mDefaultImageId, mErrorImageId));
// update the tag to be the new bitmap container.
        setTag(newContainer);
// look at the contents of the new container. if there is a bitmap, load it.
        final Bitmap bitmap = newContainer.getBitmap();
        if (bitmap != null) {
            setImageBitmap(bitmap);
        }
    }
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        loadImageIfNecessary();
    }
    @Override
    protected void onDetachedFromWindow() {
        ImageContainer oldContainer = (ImageContainer) getTag();
        if (oldContainer != null) {
// If the view was bound to an image request, cancel it and clear
// out the image from the view.
            oldContainer.cancelRequest();
            setImageBitmap(null);
// also clear out the tag so we can reload the image if necessary.
            setTag(null);
        }
        super.onDetachedFromWindow();
    }
    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        invalidate();
    }
}

build.gradle

compile 'com.github.chrisbanes.photoview:library:+'

xml

<com.xyz.NetworkImageView
            android:id="@+id/imageitem"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="matrix"
            android:layout_gravity="center"
            android:adjustViewBounds="true"
            android:background="@drawable/image_loading" />

ImageView is inside FrameLayout

    <FrameLayout
        android:id="@+id/image_holder"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="@color/black"
        >

Image before zooming enter image description here Image after zooming enter image description here

Answer

Salmaan picture Salmaan · Nov 30, 2014

Better try a different approach if youre stuck

You can find below a link to a class created by Jason Polites that will allow you to handle pinch zooms on custom ImageViews: https://github.com/jasonpolites/gesture-imageview.

Just include this package into your application and then you will be able to use a custom GestureImaveView in your XML files:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gesture-image="http://schemas.polites.com/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<com.polites.android.GestureImageView
    android:id="@+id/image"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/image"
    gesture-image:min-scale="0.1"
    gesture-image:max-scale="10.0"
    gesture-image:strict="false"/>

This class handles pinch zooms, but also double taps.

Answer credit goes to Yoann :)