2012-11-20 26 views
6

Ho una vista personalizzata con scorrimento implementata, ma sembra che ENDLESS scorra sull'immagine.
Anche quando trovo il bordo dell'immagine, continua a scorrere fino a uno sfondo vuoto.Problema Android: visualizzazione con scorrimento infinito

Non riesco a utilizzare una WebView perché ho anche un Sutff Canvas.
Qualcuno sa come impostare i limiti per questo problema?
Come adattare i bordi dell'immagine per lo scorrimento?


MODIFICA: Ho trovato la soluzione migliore con l'aiuto di @JosephEarl.
Ho impostato solo i limiti sinistro e superiore perché la mia immagine è più grande dello schermo.
Inoltre I disattiva i limiti mentre si utilizza la funzione zoom, altrimenti non potrei più spostarlo.

1) Nel caso ACTION_MOVE del vostro onTouch evento, inser questo codice:

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) Accendere o disattivare i limiti, mentre si utilizza lo zoom.
Aggiungere il seguente codice al vostro caso 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; 

} 


E questo è tutto.
Ecco tutti i metodi relativi e completa onTouch evento:

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 

risposta

2

Sembra dal codice che in nessun punto fa si tenta di rilevare la dimensione dell'area scorrevole e limitare la posizione di questi limiti , cioè dovresti controllare per assicurarti che mPosX e mPosY non superino i loro limiti.

Il sistema non limiterà automaticamente la posizione della vista personalizzata, è qualcosa che devi fare tu stesso.

Il limite superiore e sinistro sarà 0, 0 - è necessario assicurarsi che mPosX e mPosY non siano maggiori di questo.

Il limite destro sarà (larghezza della vista contenitore - larghezza della vista a scorrimento) - questo dovrebbe essere negativo (se è maggiore quindi impostare il limite destro su 0) e si dovrebbe assicurarsi che mPosX non sia inferiore a Questo. Il limite inferiore sarà (altezza del contenitore - altezza della vista a scorrimento) - questo dovrebbe essere nuovamente negativo e dovresti assicurarti che mPosY non sia inferiore a quello.

In sintesi, quando inizia evento di tocco calcolano i limiti:

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

Dove imageWidth e imageHeight sono la larghezza e l'altezza di tutto ciò che sta scorrendo.

Poi durante lo scorrimento assicurarsi che i limiti siano rispettate:

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

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

Questo è quello che non so come fare: P –

+1

Aggiornato con le informazioni su come fare questo. –

+0

Ora non c'è scorrimento sull'immagine! :( –