I have a custom view with embedded scrolling, but it looks like scrolling over an ENDLESS album.
Even when I find the edge of the image, it keeps scrolling to a blank background.
I cannot use WebView because I also have a Canvas sutff.
Does anyone know how to set limits for this problem?
How to place the edges of the image for scrolling?
EDIT: I found a better solution using @JosephEarl.
I set only the left and top borders, because my image is larger than the screen.
Also, I turn off the borders when using the zoom function, otherwise I could no longer move it.
1) In case of ACTION_MOVE of your onTouch event, paste this code:
if(!isZoomed) { if(mPosX < 0) mPosX = 0; else if(mPosX > mWidth) mPosX = mWidth; if(mPosY < 0) mPosY = 0; else if(mPosY > mHeight) mPosY = mHeight; }
2) Turn borders on or off while using zoom.
Add the following code to your ACTION_POINTER_UP case:
case MotionEvent.ACTION_POINTER_UP: { final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = ev.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = ev.getX(newPointerIndex); mLastTouchY = ev.getY(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); isZoomed = true; } else isZoomed = false; break; }
And it's all.
Here are all the related methods and the full onTouch event:
private float scaleFactor = 1.f; private ScaleGestureDetector detector; private static final int INVALID_POINTER_ID = -1; private int mActivePointerId = INVALID_POINTER_ID; private float mPosX; private float mPosY; private float mLastTouchX; private float mLastTouchY; private float mWidth; private float mHeight; private boolean isZoomed = false; // OTHER CODE GOES HERE @Override public boolean onTouchEvent(MotionEvent ev) { detector.onTouchEvent(ev); final int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); mLastTouchX = x; mLastTouchY = y; mActivePointerId = ev.getPointerId(0); break; } case MotionEvent.ACTION_MOVE: { final int pointerIndex = ev.findPointerIndex(mActivePointerId); final float x = ev.getX(pointerIndex); final float y = ev.getY(pointerIndex); if (!detector.isInProgress()) { final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; mPosX += dx; mPosY += dy; if(!isZoomed) { if(mPosX < 0) mPosX = 0; else if(mPosX > mWidth) mPosX = mWidth; if(mPosY < 0) mPosY = 0; else if(mPosY > mHeight) mPosY = mHeight; } invalidate(); } mLastTouchX = x; mLastTouchY = y; break; } case MotionEvent.ACTION_UP: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_CANCEL: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_POINTER_UP: { final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = ev.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = ev.getX(newPointerIndex); mLastTouchY = ev.getY(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); isZoomed = true; } else isZoomed = false; break; } } return true; } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { scaleFactor *= detector.getScaleFactor(); scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM)); invalidate(); return true; } } @Override protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){ super.onSizeChanged(xNew, yNew, xOld, yOld); mWidth = xNew; mHeight = yNew; } // OTHER CODE GOES HERE
source share