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.
ViewPager in Android allows the user to flip left and right through pages of data. In our android ViewPager application we'll implement a ViewPager that swipes through three views with different images and texts.
basically in ViewPager you can scroll only one item at time (either left or right), and in RecyclerView you can scroll to any index. it all depends on your requirements how you want to use it. you need to develop fragments for ViewPages, one for each page.
ViewPager2 is an improved version of the ViewPager library that offers enhanced functionality and addresses common difficulties with using ViewPager . If your app already uses ViewPager , read this page to learn more about migrating to ViewPager2 .
This method may be called by the ViewPager to obtain a title string to describe the specified page. This method is deprecated.
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
}
});
}
}
I got it to work by adding this code:
if(deltaX == 0 && saveScale == 1.0 )
startInterceptEvent();
else
stopInterceptEvent();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With