2012-11-20 8 views
6

Ich habe eine benutzerdefinierte Ansicht mit Bildlauf implementiert, aber es scheint wie ein endloser Bildlauf über das Bild.
Auch wenn ich den Rand des Bildes finde, scrollt es weiter auf einen leeren Hintergrund.Android-Problem: Ansicht mit endlosem Bildlauf

Ich kann ein WebView nicht verwenden, weil ich auch etwas Canvas sutff habe.
Kann jemand für dieses Problem Grenzen festlegen?
Wie passen die Kanten des Bildes für den Bildlauf?


EDIT: Ich fand die beste Lösung mit @JosephEarl Hilfe.
Ich setze nur linke und obere Grenzen, weil mein Bild größer ist als der Bildschirm.
Auch ich ausschalten die Grenzen bei der Verwendung der Zoom-Funktion, sonst konnte ich es nicht mehr bewegen.

1) Im ACTION_MOVE Fall Ihrer OnTouch Ereignis, inser dieser 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) Schalten Sie oder die Grenzen aus, während Zoom verwendet wird.
Fügen Sie den folgenden Code in Ihre ACTION_POINTER_UP Fall:

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; 

} 


Und das ist alles.
Hier alle zugehörigen Methoden und vollständige OnTouch Veranstaltung:

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 

Antwort

2

Es aus dem Code scheint, dass zu keinem Zeitpunkt haben Sie die Größe des rollbaren Bereich zu erfassen versuchen, und die Position dieser Grenzen zu begrenzen , dh Sie sollten sicherstellen, dass mPosX und mPosY ihre Grenzen nicht überschreiten.

Das System wird nicht automatisch die Position Ihrer benutzerdefinierten Ansicht einschränken, das müssen Sie selbst tun.

Die obere und linke Grenze wird 0, 0 - Sie sollten sicherstellen, mPosX und mPosY sind nicht größer als das.

Die rechte Grenze wird (Breite der Containeransicht - Breite der Bildlaufansicht) sein - dies sollte negativ sein (wenn es größer ist, dann setze die rechte Grenze auf 0) und du solltest sicherstellen, dass mPosX nicht kleiner ist Dies. Die untere Grenze wird (Höhe des Containers - Höhe der Scroll-Ansicht) sein - das sollte wieder negativ sein und Sie sollten sicherstellen, dass mPosY nicht weniger als das ist.

Um es zusammenzufassen, wenn die Berührungsereignis beginnt die Grenzen berechnen:

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

Wo imageWidth und imageHeight sind die Breite und Höhe von was auch immer Sie scrollen.

Dann beim Scrollen sicherstellen, dass die Grenzen befolgt werden:

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

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

Das ist, was ich nicht weiß, wie zu tun: P –

+1

Aktualisiert mit Informationen darüber, wie dies zu tun. –

+0

Jetzt gibt es keine Scroll über das Bild! :( –

Verwandte Themen