6

I'd like to use ImageViewZoom with Universal Image Loader in ImagePagerActivity.

I am able to zoom the image, Swipe to the next image. But i am facing problem when image is in Zoom position.

enter image description here

if an image is zoomed and i am at center position, if i want to see the right side part of the same image and swipe left it is going to the next image. Please help me in doing this.

here is my XML code:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="1dip" >

  <it.sephiroth.android.library.imagezoom.ImageViewTouch
     android:layout_weight="1"
     android:id="@+id/image"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:scaleType="fitCenter" />

  <ProgressBar
    android:id="@+id/loading"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:visibility="gone" />

</FrameLayout>

EDIT:

Thank you NOSTRA, Now i am able to control the zoom and slide with the below code. But the problem with Multi touch zoom. I am not able to zoom with two fingers.

Here is my previous code(working fine with two finger):

public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {


        @Override
        public boolean onScale( ScaleGestureDetector detector ) {
            Log.d( LOG_TAG, "onScale" );
            float span = detector.getCurrentSpan() - detector.getPreviousSpan();
            float targetScale = mCurrentScaleFactor * detector.getScaleFactor();
            if ( mScaleEnabled ) {
                targetScale = Math.min( getMaxZoom(), Math.max( targetScale, getMinZoom()-0.1f ) );
                zoomTo( targetScale, detector.getFocusX(), detector.getFocusY() );
                mCurrentScaleFactor = Math.min( getMaxZoom(), Math.max( targetScale, getMinZoom()-1.0f ) );
                mDoubleTapDirection = 1;
                invalidate();
                return true;
            }
            return false;
        }
    }

And here is the Modified one:

public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            externalScaleListener.onScaleBegin();
                return super.onScaleBegin(detector);
        }
        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            externalScaleListener.onScaleEnd(mCurrentScaleFactor);
        }
    }
wolverine
  • 1,665
  • 5
  • 24
  • 43
  • Hi I am also looking for the same.. Have you resolved issue. When i tried to load image with ImageViewTouch in ViewPager Activity i cant able to see image. – sam_k Apr 25 '13 at 04:21
  • Please Help me out to solve my issue – sam_k Apr 25 '13 at 04:21
  • @Sam_k, the below code works perfectly... – wolverine Apr 25 '13 at 09:21
  • Have u did this thing with Universal Image loader Page activity and ImageViewTouch? I am also going to do that .. Am i right? – sam_k Apr 25 '13 at 10:21
  • Yes.. I already did this in My App.. You can do it.. – wolverine Apr 25 '13 at 12:00
  • Ya sure.. If i Will face any issue i will contact you please help me if needed. – sam_k Apr 25 '13 at 14:50
  • Sure... I'll help you.. – wolverine Apr 25 '13 at 15:16
  • what is this `mCurrentScaleFactor = scale;` ? I cant able to find this things in ImageviewTouch? this member variable in super class? – sam_k Apr 26 '13 at 10:53
  • this is in ImageViewTouch class only.. this is used to restrict the pager action. – wolverine Apr 26 '13 at 12:27
  • thanks for answer. But it was not declared there.. I have to declare any member variable there? – sam_k Apr 26 '13 at 12:53
  • @wolverine, so with the code below the problem of looking around the image while zoomed in is gone? or did you implement the gesture-imageview? I can't seem, to get it to work. I would be happy for some help. First you modify the Imageviewtouch and build a new file to put in libs. Then do you create a DeactivableViewPager.java file? and then implement it into the "Imagepageractivity"? I just can't seem to get it to work. – Joe May 07 '13 at 16:10

2 Answers2

8

First you must be able to listen scaling of image. ImageViewTouch doesn't support this feature (e.g gesture-imageview support it) so you should implement it yourself.

Change ImageViewTouch.java like this:

public class ImageViewTouch extends ImageViewTouchBase {

    ...

    private OnPageScaleListener externalScaleListener;

    public void setOnScaleListener(OnPageScaleListener onScaleListener) {
        this.externalScaleListener = onScaleListener;
    }

    public interface OnPageScaleListener {
        void onScaleBegin();

        void onScaleEnd(float scale);
    }

    @Override
    protected void onZoom(float scale) {
        super.onZoom(scale);
        if (!mScaleDetector.isInProgress()) {
            mCurrentScaleFactor = scale;
            externalScaleListener.onScaleEnd(scale);
        }
    }

    public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            externalScaleListener.onScaleBegin();
                return super.onScaleBegin(detector);
        }

        ...

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            externalScaleListener.onScaleEnd(mCurrentScaleFactor);
        }
    }

    ...
}

Then use next implementation of ViewPager in your application:

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;

/**
 * {@link ViewPager} which can be deactivated (ignore touch events)
 * 
 * @author Sergey Tarasevich
 * @created 19.07.2012
 */
public class DeactivableViewPager extends ViewPager {

    private boolean activated = true;

    public DeactivableViewPager(Context context) {
        super(context);
    }

    public DeactivableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void activate() {
        activated = true;
    }

    public void deactivate() {
        activated = false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (activated) {
            try {
                return super.onInterceptTouchEvent(event);
            } catch (Exception e) { // sometimes happens
                return true;
            }
        } else {
        return false;
    }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        try {
            return super.onTouchEvent(event);
        } catch (Exception e) {
            return true;
        }
    }
}

Then in your ViewPager's adapter you should set next scale listener for your ImageViewTouch:

ImageViewTouch imageView = ...;
imageView.setOnScaleListener(new OnPageScaleListener() {
    @Override
    public void onScaleBegin() {
        viewPager.deactivate();
    }

    @Override
    public void onScaleEnd(float scale) {
        if (scale > 1.0) {
            viewPager.deactivate();
        } else {
            viewPager.activate();
        }
    }
});

imageLoader.displayImage(url, imageView, ...);

And don't forget set big values for maxImage***ForMemoryCache in ImageLoader's configuration so UIL won't downscale original images during decoding to Bitmaps:

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
        ...
        .memoryCacheExtraOptions(3000, 3000)
        ...
        .build();
nostra13
  • 12,377
  • 3
  • 33
  • 43
  • Hi, I used gesture-imageview also, even though i am getting same problem. – wolverine Nov 16 '12 at 06:19
  • i am able to control the image zoom and slide with the above using code, But i am able to zoom by using only double tap. I want zoom functionality by using the two fingers also. How can i do it. Pls see my edit. – wolverine Nov 16 '12 at 06:55
  • You should not to replace ScaleListener but to append ```onScaleBegin()``` and ```onScaleEnd()``` methods. There was the 3rd method... – nostra13 Nov 16 '12 at 08:03
  • @NOSTRA After adding this class `DeactivableViewPager` in UIL. after this what i have to do ? I have to extends this class instead of PageAdapter? – sam_k Apr 26 '13 at 11:30
  • @Sam_k No, you still extend PagerAdapter, but you change the type of the instance variable ViewPager to DeactivableViewPager and in ImagePagerAdapter instantiateItem method you change the line to ImageViewTouch imageView = (ImageViewTouch) imageLayout.findViewById(R.id.pager_image); – brendan Jul 30 '13 at 19:17
  • @NOSTRA I added your code and this allows me to successfully zoom in and out, however the pager activity will sometimes not allow me to go to the next image. If I rescale the image by zooming in or out, then I am then able to go to the next image. I put print statements in the onScale and it looks like it happens when the scale > 1. Do you know what could be causing this issue? – brendan Jul 31 '13 at 22:03
0

I was having trouble with pre-zoomed images in viewPager, but now its alright and solved the problem.

You have to search the ImageViewTouchBase class for this line:

protected DisplayType mScaleType = DisplayType.NONE;

then change it to:

protected DisplayType mScaleType = DisplayType.FIT_TO_SCREEN;

By default, DisplayType is set to NONE, its simple, just use FIT_TO_SCREEN and your images will be in the default size when sliding in viewPager.

Cheers


You can set those properties to make image fit to screen always

<it.sephiroth.android.library.imagezoom.ImageViewTouch
    android:id="@+id/iv_pager_image"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:adjustViewBounds="true"
    android:contentDescription="@string/descr_image"
    android:scaleType="matrix" />
AZ_
  • 21,688
  • 25
  • 143
  • 191
blueware
  • 5,205
  • 1
  • 40
  • 60