0

我遇到問題。我從這裏使用了TouchImageView代碼 - https://github.com/MikeOrtiz/TouchImageView。我已經實現了雙擊功能。它工作正常,但現在我無法在放大時拖動圖像。通過手勢縮放(縮放縮放)可以正常工作,我無法在縮放圖像上導航。我不知道爲什麼。這裏是我的實際代碼:實施雙擊到TouchImageView - 拖動圖片現在不起作用

 package com.example.testy; 

    import android.content.Context; 
    import android.graphics.Bitmap; 
    import android.graphics.Matrix; 
    import android.graphics.PointF; 
    import android.util.AttributeSet; 
    import android.view.GestureDetector; 
    import android.view.GestureDetector.SimpleOnGestureListener; 
    import android.view.MotionEvent; 
    import android.view.ScaleGestureDetector; 
    import android.view.View; 
    import android.widget.ImageView; 

    public class TouchImageView extends ImageView { 

     Matrix matrix = new Matrix(); 

     // We can be in one of these 3 states 
     static final int NONE = 0; 
     static final int DRAG = 1; 
     static final int ZOOM = 2; 
     int mode = NONE; 

     // Remember some things for zooming 
     PointF last = new PointF(); 
     PointF start = new PointF(); 
     float minScale = 1f; 
     float maxScale = 3f; 
     float[] m; 

     float redundantXSpace, redundantYSpace; 

     float width, height; 
     static final int CLICK = 3; 
     float saveScale = 1f; 
     float right, bottom, origWidth, origHeight, bmWidth, bmHeight; 

     ScaleGestureDetector mScaleDetector; 
     GestureDetector gestureDetector; 
     Context context; 

     public TouchImageView(Context context) { 
      super(context); 
      sharedConstructing(context); 
     } 

     public TouchImageView(Context context, AttributeSet attrs) { 
      super(context, attrs); 
      sharedConstructing(context); 
     } 

     private void sharedConstructing(Context context) { 
      gestureDetector = new GestureDetector(new DoubleTapGestureListener()); 
      super.setClickable(true); 
      this.context = context; 
      mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
      matrix.setTranslate(1f, 1f); 
      m = new float[9]; 
      setImageMatrix(matrix); 
      setScaleType(ScaleType.MATRIX); 

      setOnTouchListener(new OnTouchListener() { 

       @Override 
       public boolean onTouch(View v, MotionEvent event) { 
        if (gestureDetector.onTouchEvent(event)) { 
         return true; // podwojne klikniecie i koniec imprezy 
        } 
        mScaleDetector.onTouchEvent(event); 

        matrix.getValues(m); 
        float x = m[Matrix.MTRANS_X]; 
        float y = m[Matrix.MTRANS_Y]; 
        PointF curr = new PointF(event.getX(), event.getY()); 

        switch (event.getAction()) { 
        case MotionEvent.ACTION_DOWN: 
         last.set(event.getX(), event.getY()); 
         start.set(last); 
         mode = DRAG; 
         break; 
        case MotionEvent.ACTION_MOVE: 
         if (mode == DRAG) { 
          float deltaX = curr.x - last.x; 
          float deltaY = curr.y - last.y; 
          float scaleWidth = Math.round(origWidth * saveScale); 
          float scaleHeight = Math.round(origHeight * saveScale); 
          if (scaleWidth < width) { 
           deltaX = 0; 
           if (y + deltaY > 0) 
            deltaY = -y; 
           else if (y + deltaY < -bottom) 
            deltaY = -(y + bottom); 

          } else if (scaleHeight < height) { 
           deltaY = 0; 
           if (x + deltaX > 0) 
            deltaX = -x; 
           else if (x + deltaX < -right) 
            deltaX = -(x + right); 

          } else { 
           if (x + deltaX > 0) 
            deltaX = -x; 
           else if (x + deltaX < -right) 
            deltaX = -(x + right); 

           if (y + deltaY > 0) 
            deltaY = -y; 
           else if (y + deltaY < -bottom) 
            deltaY = -(y + bottom); 

          } 
          matrix.postTranslate(deltaX, deltaY); 
          last.set(curr.x, curr.y); 
         } 
         break; 

        case MotionEvent.ACTION_UP: 
         mode = NONE; 
         int xDiff = (int) Math.abs(curr.x - start.x); 
         int yDiff = (int) Math.abs(curr.y - start.y); 
         if (xDiff < CLICK && yDiff < CLICK) 
          performClick(); 
         break; 

        case MotionEvent.ACTION_POINTER_UP: 
         mode = NONE; 
         break; 
        } 
        setImageMatrix(matrix); 
        invalidate(); 
        return true; // indicate event was handled 
       } 

      }); 
     } 

     @Override 
     public void setImageBitmap(Bitmap bm) { 
      super.setImageBitmap(bm); 
      if (bm != null) { 
       bmWidth = bm.getWidth(); 
       bmHeight = bm.getHeight(); 
      } 
     } 

     public void setMaxZoom(float x) { 
      maxScale = x; 
     } 

     public boolean canScrollHorizontally(int direction) { //used to cooparate with ViewPager 
      matrix.getValues(m); 
      float x = Math.abs(m[Matrix.MTRANS_X]); 
      float scaleWidth = Math.round(origWidth * saveScale); 

      if (scaleWidth < width) { 
       return false; 

      } else { 
       if (x - direction <= 0) 
        return false; // reach left edge 
       else if (x + width - direction >= scaleWidth) 
        return false; // reach right edge 

       return true; 
      } 
     } 

     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
      super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
      width = MeasureSpec.getSize(widthMeasureSpec); 
      height = MeasureSpec.getSize(heightMeasureSpec); 
      // Fit to screen. 
      float scale; 
      float scaleX = width/bmWidth; 
      float scaleY = height/bmHeight; 
      scale = Math.min(scaleX, scaleY); 
      matrix.setScale(scale, scale); 
      setImageMatrix(matrix); 
      saveScale = 1f; 

      // Center the image 
      redundantYSpace = height - (scale * bmHeight); 
      redundantXSpace = width - (scale * bmWidth); 
      redundantYSpace /= 2; 
      redundantXSpace /= 2; 

      matrix.postTranslate(redundantXSpace, redundantYSpace); 

      origWidth = width - 2 * redundantXSpace; 
      origHeight = height - 2 * redundantYSpace; 
      right = width * saveScale - width - (2 * redundantXSpace * saveScale); 
      bottom = height * saveScale - height 
        - (2 * redundantYSpace * saveScale); 
      setImageMatrix(matrix); 
     } 

     public boolean isZoomed() { 
      return saveScale > minScale; 
     } 

     public void zoomIn() { 

      System.out.println("Zoom in!"); 

      saveScale = maxScale; 
      matrix.setScale(saveScale, saveScale); 
      setImageMatrix(matrix); 
      invalidate(); 
     } 

     public void zoomOut() { 

      saveScale = minScale; 
      matrix.setScale(saveScale, saveScale); 
      setImageMatrix(matrix); 
      invalidate(); 

      System.out.println("Zoom out!"); 
     } 

     private class DoubleTapGestureListener extends SimpleOnGestureListener { 

      @Override 
      public boolean onDown(MotionEvent e) { 
       return true; 
      } 

      // event when double tap occurs 
      @Override 
      public boolean onDoubleTap(MotionEvent e) { 
       float x = e.getX(); 
       float y = e.getY(); 

       if (isZoomed()) { 
        zoomOut(); 
       } else { 
        zoomIn(); 
       } 
       return true; 
      } 

     } 

     private class ScaleListener extends 
       ScaleGestureDetector.SimpleOnScaleGestureListener { 
      @Override 
      public boolean onScaleBegin(ScaleGestureDetector detector) { 
       mode = ZOOM; 
       return true; 

      } 

      @Override 
      public boolean onScale(ScaleGestureDetector detector) { 
       float mScaleFactor = detector.getScaleFactor(); 
       float origScale = saveScale; 
       saveScale *= mScaleFactor; 
       if (saveScale > maxScale) { 
        saveScale = maxScale; 
        mScaleFactor = maxScale/origScale; 
       } else if (saveScale < minScale) { 
        saveScale = minScale; 
        mScaleFactor = minScale/origScale; 
       } 
       right = width * saveScale - width 
         - (2 * redundantXSpace * saveScale); 
       bottom = height * saveScale - height 
         - (2 * redundantYSpace * saveScale); 
       if (origWidth * saveScale <= width 
         || origHeight * saveScale <= height) { 
        matrix.postScale(mScaleFactor, mScaleFactor, width/2, 
          height/2); 
        if (mScaleFactor < 1) { 
         matrix.getValues(m); 
         float x = m[Matrix.MTRANS_X]; 
         float y = m[Matrix.MTRANS_Y]; 
         if (mScaleFactor < 1) { 
          if (Math.round(origWidth * saveScale) < width) { 
           if (y < -bottom) 
            matrix.postTranslate(0, -(y + bottom)); 
           else if (y > 0) 
            matrix.postTranslate(0, -y); 
          } else { 
           if (x < -right) 
            matrix.postTranslate(-(x + right), 0); 
           else if (x > 0) 
            matrix.postTranslate(-x, 0); 
          } 
         } 
        } 
       } else { 
        matrix.postScale(mScaleFactor, mScaleFactor, 
          detector.getFocusX(), detector.getFocusY()); 
        matrix.getValues(m); 
        float x = m[Matrix.MTRANS_X]; 
        float y = m[Matrix.MTRANS_Y]; 
        if (mScaleFactor < 1) { 
         if (x < -right) 
          matrix.postTranslate(-(x + right), 0); 
         else if (x > 0) 
          matrix.postTranslate(-x, 0); 
         if (y < -bottom) 
          matrix.postTranslate(0, -(y + bottom)); 
         else if (y > 0) 
          matrix.postTranslate(0, -y); 
        } 
       } 
       return true; 

      } 
    } 
} 

你有什麼問題可能是什麼問題?

謝謝!

+0

你有什麼想法嗎? – michalsol

回答

1

我有同樣的問題。這是我所做的;

  1. 同時聲明在上面的檢測器(如您已完成)

    ScaleGestureDetector mScaleDetector;  
    GestureDetector mDoubleTapDetector; 
    
  2. 實例化上面sharedConstructing(...)(你幹得)變量

    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());  
    mDoubleTapDetector = new GestureDetector(context, new DoubleTapListener()); 
    

    注意:也爲GestureDetector提供上下文。

  3. 在onTouch(...)中先寫下下面的代碼;

    boolean result = mScaleDetector.onTouchEvent(event);     
    // result is always true here, so we need another way to check scalling gesture progress.   
    boolean isScaling = result = mScaleDetector.isInProgress(); 
    if (!isScaling) { 
        // if no scaling is performed check for other gestures (fling, long tab, etc.) 
        mDoubleTapDetector.onTouchEvent(event); 
    } 
    
  4. 添加另一個私有類DoubleTapListener(...)

    private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener{ 
        @Override 
        public boolean onDoubleTap(MotionEvent e) { 
        Log.e(TAG,"onDoubleTap"); 
        return super.onDoubleTap(e); 
        }    
    } 
    

就是這樣。我希望這可以幫助你。