2013-08-29 113 views
1

這是放大布局。捏放大android的佈局

public class Zoom extends FrameLayout { 

    /** 
    * 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 = 2.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 = 0; 
    private String miniMapCaption; 
    private float miniMapCaptionSize = 0; 
    private int miniMapCaptionColor = Color.WHITE;*/ 
    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 Zoom(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(); 
     // } 
    } 
} 
在我的主要活動

我包括這樣

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.grd_flr); 
    View v = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.grd_flr, null, false); 

    v.setLayoutParams(new LinearLayout.LayoutParams(android.widget.LinearLayout.LayoutParams.FILL_PARENT, android.widget.LinearLayout.LayoutParams.FILL_PARENT)); 

    zoom = new Zoom(this); 
    zoom.addView(v); 
} 

佈局現在我的佈局縮放上我想掐放大這方面,我該怎麼辦能有一個人幫我與屏幕的水龍頭這個。在此先感謝您的朋友

回答

-2
+2

我想捏縮放我的佈局哥們不是imageview。你能幫助我一些其他的技巧嗎? – Ashu

+0

你的答案仍然在這些鏈接。查看第二和第三個鏈接。 –

0

@覆蓋 公共布爾的onTouchEvent(MotionEvent事件){

switch (event.getAction() & MotionEvent.ACTION_MASK) { 

     // Gesture starts 

     case MotionEvent.ACTION_DOWN: 
      firstFingerpreviousX = event.getX(); 
      firstFingerpreviousY = event.getY(); 
      touchState = TOUCH; 
      break; 

     // Second finger is now on the show 

     case MotionEvent.ACTION_POINTER_DOWN: 
      touchState = PINCH; 
      secondFingerpreviousX = event.getX(1); 
      secondFingerpreviousY = event.getY(1); 
      distance1 = makeDistance(firstFingerpreviousX, 
        firstFingerpreviousY, secondFingerpreviousX, 
        secondFingerpreviousY); 
      break; 

     // Fingers are moving 

     case MotionEvent.ACTION_MOVE: 
      System.out.println(touchState); 

      if (touchState == PINCH) { 
       firstFingernewX = event.getX(0); 
       firstFingernewY = event.getX(0); 
       secondFingernewX = event.getX(1); 
       secondFingernewY = event.getY(1); 
       distance2 = makeDistance(firstFingernewX, firstFingernewY, 
         secondFingernewX, secondFingernewY); 
       break; 
      } 
      break; 

     // Second finger gets tired 

     case MotionEvent.ACTION_POINTER_UP: 
      touchState = ENDOFPINCH; 
      // We calculate the distances between the fingers 
      // to know if there is zoom in or out 
      if (distance2 > distance1) { 
       System.out.println("Zoom in detected"); 
      } else { 
       System.out.println("Zoom out detected"); 
      } 
      break; 
    } 
    return true; 
} 

// Pythagorean Theorem distance maker method 

public static float makeDistance(float x1, float y1, float x2, float y2) { 
    float delta1 = (x2 - x1) * (x2 - x1); 
    float delta2 = (y2 - y1) * (y2 - y1); 
    float distance = (float) Math.sqrt(delta1 + delta2); 
    return distance; 
} 

添加到您的代碼,並確保您的佈局是線性的,設定其方向。

+0

您的代碼的第一行沒有正確縮進(使用4個空格) –