如何在Android ImageView中限制图像平移边界

3
我有一个带有多点触控的imageView,大致基于教程。那里的评论者之一提出了一种限制图像拖动到图像边缘以外的半脏方法,这样图像边缘就不能被拖动到其边缘之外。这种方法有些有效,但并不完全。它只限制了两个边缘的拖动。
有没有人知道一种更简洁和实用的限制图像拖动的方法?
这是Android应用程序开发中非常重要的概念,尚未得到充分解决......
我想到了以下几个想法:
1) 当缩放= 1.0F(即最小缩放)时,设置setScaleType(scaleType.fitXY),仅当缩放> 1.0f时启用拖动
2) 当缩放> 1.0f时,设置setScaleType(scaleType.MATRIX),然后确定图像边界和屏幕尺寸,并以某种对我来说太聪明的方式,使用if语句仅在图像边缘不在屏幕上时才允许拖动。我不知道如何声明它。
无论如何,为了完整起见,以下是来自该链接的限制pan代码。这似乎是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);
2个回答

4
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)之前,请使用以下代码:


3

我知道这已经相当老了,但可以尝试这个。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对象中更加简洁,该对象还会计算宽度和高度。 - Swindler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接