2014-10-03 88 views
0

我有以下情況:Android的縮放和平移和兒童拖放上長按

ZoomAndPanLayout 
    | 
    +---> ImageView 
    | 
    +---> FrameLayout (DragLayer) 
      | 
      +---> One or more controls. A view with a circle drawn on it. 

有了一些小的問題,因爲我不喜歡現在大概屏幕綁定的ZoomAndPanLayout工作。我實現ZoomAndPan這樣的:

public class ZoomAndPanLayout extends FrameLayout { 

    //region Constants 

    public static final float DEFAULT_MIN_SCALE_FACTOR = 1.0f; 
    public static final float DEFAULT_MAX_SCALE_FACTOR = 5.0f; 

    // endregion Constants 


    // region Fields 

    private float translationX = 0; 
    private float translationY = 0; 

    private float pivotX = 0; 
    private float pivotY = 0; 

    private float oldX; 
    private float oldY; 

    private float scaleFactor = 1.0f; 

    private float minScaleFactor = ZoomAndPanLayout.DEFAULT_MIN_SCALE_FACTOR; 
    private float maxScaleFactor = ZoomAndPanLayout.DEFAULT_MAX_SCALE_FACTOR; 

    private ScaleGestureDetector scaleGestureDetector = null; 

    // endregion Fields 


    // region Constructor 

    public ZoomAndPanLayout(Context context) { 
     super(context); 
     this.initialize(context); 
    } 

    public ZoomAndPanLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.initialize(context); 
    } 

    public ZoomAndPanLayout(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     this.initialize(context); 
    } 

    private void initialize(Context context) { 
     this.scaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureListener()); 
    } 


    // endregion Constructor 


    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     this.scaleGestureDetector.onTouchEvent(event); 

     switch (event.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 
      { 
       this.oldX = event.getX(); 
       this.oldY = event.getY(); 

       break; 
      } 

      case MotionEvent.ACTION_MOVE: 
      { 
       if (!this.scaleGestureDetector.isInProgress()) 
       { 
        float x = event.getX(); 
        float y = event.getY(); 

        float deltaX = x - this.oldX; 
        float deltaY = y - this.oldY; 

        this.translationX += deltaX; 
        this.translationY += deltaY; 

        this.applyTransformations(); 

        this.oldX = x; 
        this.oldY = y; 
       } 
      } 
     } 

     return true; 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event) { 
     return this.scaleGestureDetector.onTouchEvent(event); 
    } 

    private void applyTransformations() { 
     final View child = this.getChildAt(0); 

     if (child != null) 
     { 
      child.setPivotX(this.pivotX); 
      child.setPivotY(this.pivotY); 

      child.setScaleX(this.scaleFactor); 
      child.setScaleY(this.scaleFactor); 

      // TODO: bound child to screen limits 

      child.setTranslationX(this.translationX); 
      child.setTranslationY(this.translationY); 
     } 
    } 

    public Rect getChildRect() { 

     View child = this.getChildAt(0); 

     if (child != null) 
     { 
      Rect outRect = new Rect(); 

      outRect.right = (int) (child.getWidth() * child.getScaleX()); 
      outRect.bottom = (int) (child.getHeight() * child.getScaleY()); 

      int[] location = new int[2]; 
      child.getLocationOnScreen(location); 

      outRect.offset(location[0], location[1]); 

      return outRect; 
     } 
     else 
     { 
      return new Rect(0, 0, 0, 0); 
     } 
    } 

    // region Private Inner Enums, Interfaces and Classes 

    private class ScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
     private ZoomAndPanLayout upper = ZoomAndPanLayout.this; 

     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      float newScaleFactor = detector.getScaleFactor(); 
      float originalScaleFactor = upper.scaleFactor; 

      upper.scaleFactor *= newScaleFactor; 

      // Bound the scaleFactor to the min and max limits 
      if (upper.scaleFactor >= upper.maxScaleFactor) 
      { 
       upper.scaleFactor = upper.maxScaleFactor; 
       newScaleFactor = upper.maxScaleFactor/originalScaleFactor; 
      } 
      else if (upper.scaleFactor * newScaleFactor <= upper.minScaleFactor) 
      { 
       upper.scaleFactor = upper.minScaleFactor; 
       newScaleFactor = upper.minScaleFactor/originalScaleFactor; 
      } 

      // set pivot 
      View child = upper.getChildAt(0); 

      if (child != null) 
      { 
       if (newScaleFactor * child.getWidth() * upper.scaleFactor <= originalScaleFactor * child.getWidth() 
         || newScaleFactor * child.getHeight() * upper.scaleFactor <= originalScaleFactor * child.getWidth()) 
       { 
        upper.pivotX = newScaleFactor * child.getWidth()/2; 
        upper.pivotY = newScaleFactor * child.getHeight()/2; 
       } 
       else 
       { 
        upper.pivotX = detector.getFocusX(); 
        upper.pivotY = detector.getFocusY(); 
       } 
      } 

      upper.applyTransformations(); 

      return true; 
     } 
    } 

    // endregion Private Inner Enums, Interfaces and Classes 
} 

當我創建DragLayer的每個孩子我分配給他們一個OnLongClickListener,但該死的事情劑量不火。當我長時間點擊DragLayer的任何一個孩子時。

任何想法如何使用我的想法ZoomAndPanLayout或任何想法來實現這一點。如果您問自己爲什麼需要ZoomAndPanLayout,那是因爲我必須能夠縮放和平移任何佈局,而不僅僅是ImageView。

任何想法?

回答

0

可能因爲您在onTouchEvent方法中返回true。 當返回true它消耗了一個事件,並且兒童不會收到他們自己的onTouchEvent

@Override public boolean onInterceptTouchEvent(MotionEvent event) { return this.scaleGestureDetector.onTouchEvent(event); }

總是從接收的事件返回true,它也阻止孩子。