Android issue: infinite scroll view

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 
+6
source share
1 answer

As you can see from your code, you are in no way trying to determine the size of the scrollable area and limit the position to these boundaries, i.e. you should check that mPosX and mPosY do not exceed their boundaries.

The system will not automatically limit the position of your user view, this is what you need to do yourself.

The top and left borders will be 0, 0 - you need to make sure that mPosX and mPosY not larger than this.

The correct border will be (container view width - scroll width) - this should be negative (if it is larger, then set the correct border to 0), and you must make sure that mPosX not less than this. The bottom border will be (container height - scroll height) - this again should be negative, and you need to make sure that mPosY no less.

To summarize, when a touch event begins to compute the bounds:

 // Calculate our bounds. int leftBound = 0; int topBound = 0; int rightBound = imageWidth - getWidth(); if (rightBound > 0) { rightBound = 0; } int bottomBound = imageHeight - getHeight(); if (bottomBound > 0) { bottomBound = 0; } 

Where imageWidth and imageHeight are the width and height of what you scroll.

Then, while scrolling, make sure that the scores are met:

 if (mPosX > leftBound) { mPosX = leftBound; } else if (mPosX < rightBound) { mPosX = rightBound; } if (mPosY > topBound) { mPosY = topBound; } else if (mPosY < bottomBound) { mPosY = bottomBound; } 
+2
source

All Articles