ViewPager & ImageView zooming issue

13,484

Solution 1

Yes I too had the same problem not with TouchImageView.

Too solved the problem what i did is disabled the ViewPager when my view is getting the focus.

public class EnableDisableViewPager extends ViewPager {

    private boolean enabled = true;

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        if(enabled)
            return super.onInterceptTouchEvent(arg0);

        return false;
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}

so in TouchImageView implement your listener to trigger an event whether its zooming or dragging.

set listener to your view object in your Activity. So when those event occur just disable the view Pager.

Note: you will also need a mouse up event to enable the viewpager.

EDITED

This will work only for Zoom, so for ViewPager to swipe pages you should zoom back to original.

Add these code to your TouchImageView

    public class TouchImageView extends ImageView {

        ...
    private TouchEventListener touchEventListener;

        private void sharedConstructing(Context context) {
            ...

            setOnTouchListener(new OnTouchListener() {

                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    ...
                        case MotionEvent.ACTION_UP:
                            ...
                            if(touchEventListener != null)
                            {
                                if(saveScale == 1.0)
                                    touchEventListener.onZoomToOriginal();
                                else
                                    touchEventListener.onZoom();
                            }
                            break;

                        ...
                    }
                    ...
                }

            });
        }

        ...

public TouchEventListener getTouchEventListener() {
        return touchEventListener;
    }

    public void setTouchEventListener(TouchEventListener touchEventListener) {
        this.touchEventListener = touchEventListener;
    }


        public interface TouchEventListener 
        {
            void onZoom();
            void onZoomToOriginal();
        }
    }

BETTER SOLUTION

We could achieve this without extending ViewPager to a new Class by using the method given below.

requestDisallowInterceptTouchEvent(true);

And with this we could swipe without zooming out to original position as we see in Gallery and many other apps.

public class TouchImageView extends ImageView {

        ...
private void stopInterceptEvent()
{
    getParent().requestDisallowInterceptTouchEvent(true);
}

private void startInterceptEvent()
{
    getParent().requestDisallowInterceptTouchEvent(false);
}

private void sharedConstructing(Context context) {
    super.setClickable(true);
    this.context = context;
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
    matrix.setTranslate(1f, 1f);
    m = new float[9];
    setImageMatrix(matrix);
    setScaleType(ScaleType.MATRIX);

    setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            mScaleDetector.onTouchEvent(event);

            matrix.getValues(m);
            float x = m[Matrix.MTRANS_X];
            float y = m[Matrix.MTRANS_Y];
            PointF curr = new PointF(event.getX(), event.getY());

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    last.set(event.getX(), event.getY());
                    start.set(last);
                    mode = DRAG;
                    stopInterceptEvent();
                    break;
                case MotionEvent.ACTION_MOVE:
                    if (mode == DRAG) {
                        float deltaX = curr.x - last.x;
                        float deltaY = curr.y - last.y;
                        float scaleWidth = Math.round(origWidth * saveScale);
                        float scaleHeight = Math.round(origHeight * saveScale);
                        if (scaleWidth < width) {
                            deltaX = 0;
                            if (y + deltaY > 0)
                                deltaY = -y;
                            else if (y + deltaY < -bottom)
                                deltaY = -(y + bottom); 
                        } else if (scaleHeight < height) {
                            deltaY = 0;
                            if (x + deltaX > 0)
                                deltaX = -x;
                            else if (x + deltaX < -right)
                                deltaX = -(x + right);
                        } else {
                            if (x + deltaX > 0)
                                deltaX = -x;
                            else if (x + deltaX < -right)
                                deltaX = -(x + right);

                            if (y + deltaY > 0)
                                deltaY = -y;
                            else if (y + deltaY < -bottom)
                                deltaY = -(y + bottom);
                        }

                        if(deltaX == 0)
                            startInterceptEvent();
                        else
                            stopInterceptEvent();

                        matrix.postTranslate(deltaX, deltaY);
                        last.set(curr.x, curr.y);
                    }
                    break;

                case MotionEvent.ACTION_UP:
                    mode = NONE;
                    int xDiff = (int) Math.abs(curr.x - start.x);
                    int yDiff = (int) Math.abs(curr.y - start.y);
                    if (xDiff < CLICK && yDiff < CLICK)
                        performClick();
                    startInterceptEvent();
                    break;

                case MotionEvent.ACTION_POINTER_UP:
                    mode = NONE;
                    break;
            }
            setImageMatrix(matrix);
            invalidate();
            return true; // indicate event was handled
        }

    });
}
}

Solution 2

I have finally found the Subsampling Scale Image View library, which works even with standard ViewPager from Android Support Package without any customisations.

Solution 3

I got it to work by adding this code:

if(deltaX == 0 &&  saveScale == 1.0 )
    startInterceptEvent();
else
    stopInterceptEvent();
Share:
13,484
Bharath
Author by

Bharath

Senior iOS &amp; Android apps developer.

Updated on June 23, 2022

Comments

  • Bharath
    Bharath almost 2 years

    I am trying to implement a Gallery of images using ViewPager. Also, to implement zoom feature in that, I am using TouchImageView from github. I have also tried using ZoomableImageView.

    But, the problem is, if I zoom the image & if I scroll the image , then instead of image, ViewPager is getting scrolled & next view of ViewPager is getting loaded.

    If I zoom the image then if I scroll that, then image has to move instead of ViewPager

    ViewPager's next view has to load only if reach the end of the zoomed image. How to do that?

    I am not able to find that.If I touch & drag the image diagonally, only then image is getting moved. or else ViewPager's drag is getting invoked.

    ps: this is not duplicate. Zooming is done. But the problem is after image zooming.

  • Bharath
    Bharath over 11 years
    Ya please revise the TouchImageView. I am really working very hard on it. I am not able to find solution. It would be really helpful if you can help me in that!! Please update your answer with the revised TouchImageView.
  • lorenzo-s
    lorenzo-s almost 11 years
    Thank you! You saved my day!
  • Gangnaminmo Ako
    Gangnaminmo Ako over 10 years
    What are the variables width, height, right, bottom ? didn't mentioned it.
  • Learning Android
    Learning Android over 10 years
    @VivekKhandelwal thnak u very much, but the image is still being cut at the edges sometimes by the other image; Plus my image was filling its parent now it's smaller why? thanks.
  • Anil Deshmukh
    Anil Deshmukh about 10 years
    Thank you Vivek this works with me, lot of time saved, thank you again!
  • sandeepmaaram
    sandeepmaaram about 9 years
    @VivekKhandelwal Thankyou very much, its working fine
  • Nitesh Kumar
    Nitesh Kumar almost 9 years
    @VivekKhandelwal What are width, height, right and bottom?
  • Vivek Khandelwal
    Vivek Khandelwal almost 9 years
    check my GitHub fork in above comments you will get complete source
  • Tuan Chau
    Tuan Chau almost 9 years
    Thank you so much. You save my days :)