【问题标题】:How to limit image pan boundary in Android imageView如何在 Android imageView 中限制图像平移边界
【发布时间】:2011-10-04 16:24:16
【问题描述】:

我有一个大致基于this tutorial 的多点触控图像视图。那里的一位评论者提出了一种半脏方法,将图像拖动限制在图像的边界内,使图像边缘不能被拖动到其边缘之外。这种方法有点工作,但不是完全有效。它只限制两条边的拖动。

有谁知道限制图像拖动的不那么凌乱且实用的方法?

对于 Android 应用程序开发来说,这是一个非常重要的概念,但没有得到充分的解决......

我想到了以下想法:

1) setScaleType(scaleType.fitXY) 当 zoom = 1.0F(即最小缩放)时,只有在 zoom > 1.0f 时才启用拖动

2) 当缩放 > 1.0f 时,setScaleType(scaleType.MATRIX),然后您确定图像边界和屏幕尺寸,并且以某种方式对我来说太聪明了,使用 if 语句您只允许在图像边缘拖动不在屏幕上。我不知道如何声明,就是这样。

无论如何,为了完整起见,这里是来自该链接的限制平移代码。这似乎是 stackoverflow 上最受欢迎的建议,但我认为我们可以做得更好:

// limit pan
matrix.getValues(matrixValues);
float currentY = matrixValues[Matrix.MTRANS_Y];
float currentX = matrixValues[Matrix.MTRANS_X];
float currentScale = matrixValues[Matrix.MSCALE_X];
float currentHeight = height * currentScale;
float currentWidth = width * currentScale;
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
float newX = currentX+dx;
float newY = currentY+dy; 

RectF drawingRect = new RectF(newX, newY, newX+currentWidth, newY+currentHeight);
float diffUp = Math.min(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
float diffDown = Math.max(viewRect.bottom-drawingRect.bottom, viewRect.top-drawingRect.top);
float diffLeft = Math.min(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
float diffRight = Math.max(viewRect.left-drawingRect.left, viewRect.right-drawingRect.right);
if(diffUp > 0 ){
dy +=diffUp; 
}
if(diffDown < 0){
dy +=diffDown;
} 
if( diffLeft> 0){ 
dx += diffLeft;
}
if(diffRight < 0){
dx += diffRight;
}
matrix.postTranslate(dx, dy);

【问题讨论】:

    标签: android image scale


    【解决方案1】:
    private void limitDrag(Matrix m, ImageView view) {
    
    
        float[] values = new float[9];
        m.getValues(values);
        float transX = values[Matrix.MTRANS_X];
        float transY = values[Matrix.MTRANS_Y];
        float scaleX = values[Matrix.MSCALE_X];
        float scaleY = values[Matrix.MSCALE_Y];
    
        Rect bounds = view.getDrawable().getBounds();
        int viewWidth = getResources().getDisplayMetrics().widthPixels;
        int viewHeight = getResources().getDisplayMetrics().heightPixels;
    
    
    
        if(viewHeight<=480)
        {
    
            _y_up=0;
        }
        if(viewHeight>480&&viewHeight<980)
        {
    
            _y_up=140;
        }
    
        int width = bounds.right - bounds.left;
        int height = bounds.bottom - bounds.top;
        int __width=width;
        int __height=height;
        width = viewWidth / 2;
        height = viewHeight / 2;
    
    
        //height = 200 ;
        float minX = (-width) ;//* scaleX;
        float minY = (-height) ;//* scaleY;
    
    
        if ((transX) > (viewWidth)) {
    
            //_x_left
    
            transX = viewWidth;
        } else if (transX < minX) {
    
    
            transX = minX;
        }
    
    
        if ((-transX) > (viewWidth)) {
                 // _x_right
            transX = -(viewWidth);
        } else if (-transX < minX) {
    
            transX = -(minX+30);
        }
    
    
    
        if ((transY) > (viewHeight)) {
        //  _y_up
            transY =( viewHeight);
    
    
        } else if (transY < minY) {
    
            transY = (minY+_y_up);
        }
    
        if ((-transY) > (viewHeight)) {
        //  _y_down
            transY = -(viewHeight);
    
        } else if (-transY < minY) {
    
            transY = -(minY+170);
        }
    
        values[Matrix.MTRANS_X] = transX;
        values[Matrix.MTRANS_Y] = transY;
        m.setValues(values);
    }
    

    在你的 view.setImageMatrix(matrix) 上面调用它;

    【讨论】:

      【解决方案2】:

      我意识到这已经很老了,但是试试这个。 imageWidth 和 imageHeight 是未缩放的值。

      private void limitDrag(Matrix m, ImageView view, int imageWidth, int imageHeight) {
          float[] values = new float[9];
          m.getValues(values);
          float[] orig = new float[] {0,0, imageWidth, imageHeight};
          float[] trans = new float[4];
          m.mapPoints(trans, orig);
      
          float transLeft = trans[0];
          float transTop = trans[1];
          float transRight = trans[2];
          float transBottom = trans[3];
          float transWidth = transRight - transLeft;
          float transHeight = transBottom - transTop;
      
          float xOffset = 0;
          if (transWidth > view.getWidth()) {
              if (transLeft > 0) {
                  xOffset = -transLeft;
              } else if (transRight < view.getWidth()) {
                  xOffset = view.getWidth() - transRight;
              }
          } else {
              if (transLeft < 0) {
                  xOffset = -transLeft;
              } else if (transRight > view.getWidth()) {
                  xOffset = -(transRight - view.getWidth());
              }
          }
      
          float yOffset = 0;
          if (transHeight > view.getHeight()) {
              if (transTop > 0) {
                  yOffset = -transTop;
              } else if (transBottom < view.getHeight()) {
                  yOffset = view.getHeight() - transBottom;
              }
          } else {
              if (transTop < 0) {
                  yOffset = -transTop;
              } else if (transBottom > view.getHeight()) {
                  yOffset = -(transBottom - view.getHeight());
              }
          }
      
          float transX = values[Matrix.MTRANS_X];
          float transY = values[Matrix.MTRANS_Y];
      
          values[Matrix.MTRANS_X] = transX + xOffset;
          values[Matrix.MTRANS_Y] = transY + yOffset;
          m.setValues(values);
      }
      

      【讨论】:

      • 我只需要确保传入图像的宽度和高度除以 2,这样效果很好!我发现将翻译后的值存储在 RectF 对象中会稍微干净一些,它还会为您计算宽度和高度。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-24
      • 2022-07-04
      • 2020-07-11
      • 2021-04-07
      • 1970-01-01
      • 2017-05-18
      • 2020-09-25
      相关资源
      最近更新 更多