2012-11-20 73 views
6

我有一个自定义视图滚动实施,但它看起来像一个ENDLESS滚动图像。
即使当我找到图像的边缘时,它仍然保持滚动到空白背景。Android问题:查看无尽滚动

我无法使用WebView,因为我也有一些Canvas sutff。
有谁知道如何设置这个问题的限制?
如何适合滚动图像的边缘?


编辑:我用@JosephEarl帮助找到了最好的解决方案。
我刚刚设置了左侧和上限,因为我的图像比屏幕大。
另外我关闭边界使用变焦funcionality,否则我不能移动它了。

1)在您的onTouch事件,inser这种代码的情况下ACTION_MOVE:

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)打开或同时使用变焦关闭边界。
下面的代码添加到您的ACTION_POINTER_UP情况:

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; 

} 


而这一切。
这里是所有的相关方法和完整的onTouch事件:

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 

回答

2

它从你的代码似乎在任何时候,你尝试检测滚动区域的大小,并限制位置的边界,即你应该检查以确保mPosXmPosY不超过其界限。

系统不会自动限制自定义视图的位置,这是您需要自己做的事情。

顶部和左边界将是0,0 - 你应该确保mPosXmPosY不会比这更大。

右边界将是(容器视图的宽度 - 滚动视图的宽度) - 这应该是负数(如果它大于那么设置右边界为0),并且您应该确保mPosX不小于这个。底部界限将是(容器的高度 - 滚动视图的高度) - 这应该是负值,您应该确保mPosY不低于此值。

综上所述,当触摸事件开始计算范围:

// 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; 
} 

imageWidthimageHeight是宽度和高度无论你正在滚动。

然后滚动时确保边界得到遵守:

if (mPosX > leftBound) { 
    mPosX = leftBound; 
} else if (mPosX < rightBound) { 
    mPosX = rightBound; 
} 

if (mPosY > topBound) { 
    mPosY = topBound; 
} else if (mPosY < bottomBound) { 
    mPosY = bottomBound; 
} 
+0

那是什么,我不知道该怎么做:P –

+1

更新了关于如何做到这一点的信息。 –

+0

现在没有滚动图像! :( –