2016-09-07 2 views
2

GridView 집게 확대/축소 및 무한 스크롤 (랩 어라운드)

새로운 기능입니다. GridView과 협력해야하는 프로젝트가 있습니다. 한 페이지에 'n'개의 이미지가 표시되었습니다. 작업은 손가락을 늘려줌으로써 축소하고, 도달 할 때 페이지를 위로 스크롤 할 때마다 (1에서 n까지 n 개의 이미지가 포함됨) 한 번에 하나의 이미지 총 화면을 확대해야하는 것뿐만 아니라 스크롤하는 것과 같이 무한 (랩 어라운드)이 필요하지 않습니다. 페이지의 끝은 다음 페이지에서 1에서 n 개의 이미지 (이전 페이지와 동일)에서 다시 표시됩니다. 페이지 위를 스크롤하면 n에서 1 (n, n-1, n-2, ... 1)의 이미지가 표시됩니다. 위의 조건을 해결하도록 도와주세요. 나는 페이지의 n 개의 이미지를 보여주기 위해 아래의 링크를 따라왔다. this is the link I followed

답변

2

ZoomView zoomView = 새로운 ZoomView 등이 ZoomView 클래스 뭔가에보기를 추가 (이); //보기 ->; //이 활동

zoomView.addView (보기)을 의미 보기가

setContentView (zoomView); //이 위치에서 사용하십시오 setContentView (R.layout.xxxxx);

희망이 도움이

공용 클래스 ZoomView가 {

/** 
* Zooming view listener interface. 
* 
* @author karooolek 
* 
*/ 
public interface ZoomViewListener { 

    void onZoomStarted(float zoom, float zoomx, float zoomy); 

    void onZooming(float zoom, float zoomx, float zoomy); 

    void onZoomEnded(float zoom, float zoomx, float zoomy); 
} 

// zooming 
float zoom = 1.0f; 
float maxZoom = 50.0f; 
float smoothZoom = 1.0f; 
float zoomX, zoomY; 
float smoothZoomX, smoothZoomY; 
private boolean scrolling; // NOPMD by karooolek on 29.06.11 11:45 

// minimap variables 
private boolean showMinimap = false; 
private int miniMapColor = Color.BLACK; 
private int miniMapHeight = -1; 
private String miniMapCaption; 
private float miniMapCaptionSize = 10.0f; 
private int miniMapCaptionColor = Color.WHITE; 

// touching variables 
private long lastTapTime; 
private float touchStartX, touchStartY; 
private float touchLastX, touchLastY; 
private float startd; 
private boolean pinching; 
private float lastd; 
private float lastdx1, lastdy1; 
private float lastdx2, lastdy2; 

// drawing 
private final Matrix m = new Matrix(); 
private final Paint p = new Paint(); 

// listener 
ZoomViewListener listener; 

private Bitmap ch; 

public ZoomView(final Context context) { 
    super(context); 
} 

public float getZoom() { 
    return zoom; 
} 

public float getMaxZoom() { 
    return maxZoom; 
} 

public void setMaxZoom(final float maxZoom) { 
    if (maxZoom < 1.0f) { 
     return; 
    } 

    this.maxZoom = maxZoom; 
} 

public void setMiniMapEnabled(final boolean showMiniMap) { 
    this.showMinimap = showMiniMap; 
} 

public boolean isMiniMapEnabled() { 
    return showMinimap; 
} 

public void setMiniMapHeight(final int miniMapHeight) { 
    if (miniMapHeight < 0) { 
     return; 
    } 
    this.miniMapHeight = miniMapHeight; 
} 

public int getMiniMapHeight() { 
    return miniMapHeight; 
} 

public void setMiniMapColor(final int color) { 
    miniMapColor = color; 
} 

public int getMiniMapColor() { 
    return miniMapColor; 
} 

public String getMiniMapCaption() { 
    return miniMapCaption; 
} 

public void setMiniMapCaption(final String miniMapCaption) { 
    this.miniMapCaption = miniMapCaption; 
} 

public float getMiniMapCaptionSize() { 
    return miniMapCaptionSize; 
} 

public void setMiniMapCaptionSize(final float size) { 
    miniMapCaptionSize = size; 
} 

public int getMiniMapCaptionColor() { 
    return miniMapCaptionColor; 
} 

public void setMiniMapCaptionColor(final int color) { 
    miniMapCaptionColor = color; 
} 

public void zoomTo(final float zoom, final float x, final float y) { 
    this.zoom = Math.min(zoom, maxZoom); 
    zoomX = x; 
    zoomY = y; 
    smoothZoomTo(this.zoom, x, y); 
} 

public void smoothZoomTo(final float zoom, final float x, final float y) { 
    smoothZoom = clamp(1.0f, zoom, maxZoom); 
    smoothZoomX = x; 
    smoothZoomY = y; 
    if (listener != null) { 
     listener.onZoomStarted(smoothZoom, x, y); 
    } 
} 

public ZoomViewListener getListener() { 
    return listener; 
} 

public void setListner(final ZoomViewListener listener) { 
    this.listener = listener; 
} 

public float getZoomFocusX() { 
    return zoomX * zoom; 
} 

public float getZoomFocusY() { 
    return zoomY * zoom; 
} 

@Override 
public boolean dispatchTouchEvent(final MotionEvent ev) { 
    // single touch 
    if (ev.getPointerCount() == 1) { 
     processSingleTouchEvent(ev); 
    } 

    // // double touch 
    if (ev.getPointerCount() == 2) { 
     processDoubleTouchEvent(ev); 
    } 

    // redraw 
    getRootView().invalidate(); 
    invalidate(); 

    return true; 
} 

private void processSingleTouchEvent(final MotionEvent ev) { 

    final float x = ev.getX(); 
    final float y = ev.getY(); 

    final float w = miniMapHeight * (float) getWidth()/getHeight(); 
    final float h = miniMapHeight; 
    final boolean touchingMiniMap = x >= 10.0f && x <= 10.0f + w && y >= 10.0f && y <= 10.0f + h; 

    if (showMinimap && smoothZoom > 1.0f && touchingMiniMap) { 
     processSingleTouchOnMinimap(ev); 
    } else { 
     processSingleTouchOutsideMinimap(ev); 
    } 
} 

private void processSingleTouchOnMinimap(final MotionEvent ev) { 
    final float x = ev.getX(); 
    final float y = ev.getY(); 

    final float w = miniMapHeight * (float) getWidth()/getHeight(); 
    final float h = miniMapHeight; 
    final float zx = (x - 10.0f)/w * getWidth(); 
    final float zy = (y - 10.0f)/h * getHeight(); 
    smoothZoomTo(smoothZoom, zx, zy); 
} 

private void processSingleTouchOutsideMinimap(final MotionEvent ev) { 
    final float x = ev.getX(); 
    final float y = ev.getY(); 
    float lx = x - touchStartX; 
    float ly = y - touchStartY; 
    final float l = (float) Math.hypot(lx, ly); 
    float dx = x - touchLastX; 
    float dy = y - touchLastY; 
    touchLastX = x; 
    touchLastY = y; 

    switch (ev.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     touchStartX = x; 
     touchStartY = y; 
     touchLastX = x; 
     touchLastY = y; 
     dx = 0; 
     dy = 0; 
     lx = 0; 
     ly = 0; 
     scrolling = false; 
     break; 

    case MotionEvent.ACTION_MOVE: 
     if (scrolling || (smoothZoom > 1.0f && l > 30.0f)) { 
      if (!scrolling) { 
       scrolling = true; 
       ev.setAction(MotionEvent.ACTION_CANCEL); 
       super.dispatchTouchEvent(ev); 
      } 
      smoothZoomX -= dx/zoom; 
      smoothZoomY -= dy/zoom; 
      return; 
     } 
     break; 

    case MotionEvent.ACTION_OUTSIDE: 
    case MotionEvent.ACTION_UP: 

     // tap 
     if (l < 30.0f) { 
      // check double tap 
      if (System.currentTimeMillis() - lastTapTime < 500) { 
       if (smoothZoom == 1.0f) { 
        // smoothZoomTo(maxZoom, x, y); 
       } else { 
        // smoothZoomTo(1.0f, getWidth()/2.0f, getHeight()/2.0f); 
       } 
       lastTapTime = 0; 
       ev.setAction(MotionEvent.ACTION_CANCEL); 
       super.dispatchTouchEvent(ev); 
       return; 
      } 

      lastTapTime = System.currentTimeMillis(); 

      performClick(); 
     } 
     break; 

    default: 
     break; 
    } 

    ev.setLocation(zoomX + (x - 0.5f * getWidth())/zoom, zoomY + (y - 0.5f * getHeight())/zoom); 

    ev.getX(); 
    ev.getY(); 

    super.dispatchTouchEvent(ev); 
} 

private void processDoubleTouchEvent(final MotionEvent ev) { 
    final float x1 = ev.getX(0); 
    final float dx1 = x1 - lastdx1; 
    lastdx1 = x1; 
    final float y1 = ev.getY(0); 
    final float dy1 = y1 - lastdy1; 
    lastdy1 = y1; 
    final float x2 = ev.getX(1); 
    final float dx2 = x2 - lastdx2; 
    lastdx2 = x2; 
    final float y2 = ev.getY(1); 
    final float dy2 = y2 - lastdy2; 
    lastdy2 = y2; 

    // pointers distance 
    final float d = (float) Math.hypot(x2 - x1, y2 - y1); 
    final float dd = d - lastd; 
    lastd = d; 
    final float ld = Math.abs(d - startd); 

    Math.atan2(y2 - y1, x2 - x1); 
    switch (ev.getAction()) { 
    case MotionEvent.ACTION_DOWN: 
     startd = d; 
     pinching = false; 
     break; 

    case MotionEvent.ACTION_MOVE: 
     if (pinching || ld > 30.0f) { 
      pinching = true; 
      final float dxk = 0.5f * (dx1 + dx2); 
      final float dyk = 0.5f * (dy1 + dy2); 
      smoothZoomTo(Math.max(1.0f, zoom * d/(d - dd)), zoomX - dxk/zoom, zoomY - dyk/zoom); 
     } 

     break; 

    case MotionEvent.ACTION_UP: 
    default: 
     pinching = false; 
     break; 
    } 

    ev.setAction(MotionEvent.ACTION_CANCEL); 
    super.dispatchTouchEvent(ev); 
} 

private float clamp(final float min, final float value, final float max) { 
    return Math.max(min, Math.min(value, max)); 
} 

private float lerp(final float a, final float b, final float k) { 
    return a + (b - a) * k; 
} 

private float bias(final float a, final float b, final float k) { 
    return Math.abs(b - a) >= k ? a + k * Math.signum(b - a) : b; 
} 

@Override 
protected void dispatchDraw(final Canvas canvas) { 
    // do zoom 
    zoom = lerp(bias(zoom, smoothZoom, 0.05f), smoothZoom, 0.2f); 
    smoothZoomX = clamp(0.5f * getWidth()/smoothZoom, smoothZoomX, getWidth() - 0.5f * getWidth()/smoothZoom); 
    smoothZoomY = clamp(0.5f * getHeight()/smoothZoom, smoothZoomY, getHeight() - 0.5f * getHeight()/smoothZoom); 

    zoomX = lerp(bias(zoomX, smoothZoomX, 0.1f), smoothZoomX, 0.35f); 
    zoomY = lerp(bias(zoomY, smoothZoomY, 0.1f), smoothZoomY, 0.35f); 
    if (zoom != smoothZoom && listener != null) { 
     listener.onZooming(zoom, zoomX, zoomY); 
    } 

    final boolean animating = Math.abs(zoom - smoothZoom) > 0.0000001f 
      || Math.abs(zoomX - smoothZoomX) > 0.0000001f || Math.abs(zoomY - smoothZoomY) > 0.0000001f; 

    // nothing to draw 
    if (getChildCount() == 0) { 
     return; 
    } 

    // prepare matrix 
    m.setTranslate(0.5f * getWidth(), 0.5f * getHeight()); 
    m.preScale(zoom, zoom); 
    m.preTranslate(-clamp(0.5f * getWidth()/zoom, zoomX, getWidth() - 0.5f * getWidth()/zoom), 
      -clamp(0.5f * getHeight()/zoom, zoomY, getHeight() - 0.5f * getHeight()/zoom)); 

    // get view 
    final View v = getChildAt(0); 
    m.preTranslate(v.getLeft(), v.getTop()); 

    // get drawing cache if available 
    if (animating && ch == null && isAnimationCacheEnabled()) { 
     v.setDrawingCacheEnabled(true); 
     ch = v.getDrawingCache(); 
    } 

    // draw using cache while animating 
    if (animating && isAnimationCacheEnabled() && ch != null) { 
     p.setColor(0xffffffff); 
     canvas.drawBitmap(ch, m, p); 
    } else { // zoomed or cache unavailable 
     ch = null; 
     canvas.save(); 
     canvas.concat(m); 
     v.draw(canvas); 
     canvas.restore(); 
    } 

    // draw minimap 
    if (showMinimap) { 
     if (miniMapHeight < 0) { 
      miniMapHeight = getHeight()/4; 
     } 

     canvas.translate(10.0f, 10.0f); 

     p.setColor(0x80000000 | 0x00ffffff & miniMapColor); 
     final float w = miniMapHeight * (float) getWidth()/getHeight(); 
     final float h = miniMapHeight; 
     canvas.drawRect(0.0f, 0.0f, w, h, p); 

     if (miniMapCaption != null && miniMapCaption.length() > 0) { 
      p.setTextSize(miniMapCaptionSize); 
      p.setColor(miniMapCaptionColor); 
      p.setAntiAlias(true); 
      canvas.drawText(miniMapCaption, 10.0f, 10.0f + miniMapCaptionSize, p); 
      p.setAntiAlias(false); 
     } 

     p.setColor(0x80000000 | 0x00ffffff & miniMapColor); 
     final float dx = w * zoomX/getWidth(); 
     final float dy = h * zoomY/getHeight(); 
     canvas.drawRect(dx - 0.5f * w/zoom, dy - 0.5f * h/zoom, dx + 0.5f * w/zoom, dy + 0.5f * h/zoom, p); 

     canvas.translate(-10.0f, -10.0f); 
    } 

    // redraw 
    // if (animating) { 
    getRootView().invalidate(); 
    invalidate(); 
    // } 
} 

}

FrameLayout이 확장이다
관련 문제