我正在尝试使用Android手势侦听器和缩放侦听器来实现捏缩放和拖动。问题是当我执行缩小缩放时,我想要放大的图像弹跳到特定的位置。变焦位置也不居中。

以下代码演示了我要实现的内容。任何想法为什么图像跳跃(和如何纠正它)?

public class CustomView extends View {

Bitmap image;

int screenHeight;

int screenWidth;

Paint paint;

GestureDetector gestures;

ScaleGestureDetector scaleGesture;

float scale = 1.0f;

float horizontalOffset, verticalOffset;

int NORMAL = 0;

int ZOOM = 1;

int DRAG = 2;

boolean isScaling = false;

float touchX, touchY;

int mode = NORMAL;

public CustomView(Context context) {

super(context);

//initializing variables

image = BitmapFactory.decodeResource(getResources(),

R.drawable.image_name);

//This is a full screen view

screenWidth = getResources().getDisplayMetrics().widthPixels;

screenHeight = getResources().getDisplayMetrics().heightPixels;

paint = new Paint();

paint.setAntiAlias(true);

paint.setFilterBitmap(true);

paint.setDither(true);

paint.setColor(Color.WHITE);

scaleGesture = new ScaleGestureDetector(getContext(),

new ScaleListener());

gestures = new GestureDetector(getContext(), new GestureListener());

mode = NORMAL;

initialize();

}

//Best fit image display on canvas

private void initialize() {

float imgPartRatio = image.getWidth() / (float) image.getHeight();

float screenRatio = (float) screenWidth / (float) screenHeight;

if (screenRatio > imgPartRatio) {

scale = ((float) screenHeight) / (float) (image.getHeight()); // fit height

horizontalOffset = ((float) screenWidth - scale

* (float) (image.getWidth())) / 2.0f;

verticalOffset = 0;

} else {

scale = ((float) screenWidth) / (float) (image.getWidth()); // fit width

horizontalOffset = 0;

verticalOffset = ((float) screenHeight - scale

* (float) (image.getHeight())) / 2.0f;

}

invalidate();

}

@Override

protected void onDraw(Canvas canvas) {

canvas.save();

canvas.drawColor(0, Mode.CLEAR);

canvas.drawColor(Color.WHITE);

if(mode == DRAG || mode == NORMAL) {

//This works perfectly as expected

canvas.translate(horizontalOffset, verticalOffset);

canvas.scale(scale, scale);

canvas.drawBitmap(image, getMatrix(), paint);

}

else if (mode == ZOOM) {

//PROBLEM AREA - when applying pinch zoom,

//the image jumps to a position abruptly

canvas.scale(scale, scale, touchX, touchY);

canvas.drawBitmap(image, getMatrix(), paint);

}

canvas.restore();

}

public class ScaleListener implements OnScaleGestureListener {

@Override

public boolean onScale(ScaleGestureDetector detector) {

float scaleFactorNew = detector.getScaleFactor();

if (detector.isInProgress()) {

touchX = detector.getFocusX();

touchY = detector.getFocusY();

scale *= scaleFactorNew;

invalidate(0, 0, screenWidth, screenHeight);

}

return true;

}

@Override

public boolean onScaleBegin(ScaleGestureDetector detector) {

isScaling = true;

mode=ZOOM;

return true;

}

@Override

public void onScaleEnd(ScaleGestureDetector detector) {

mode = NORMAL;

isScaling = false;

}

}

public class GestureListener implements GestureDetector.OnGestureListener,

GestureDetector.OnDoubleTapListener {

@Override

public boolean onDown(MotionEvent e) {

isScaling = false;

return true;

}

@Override

public boolean onScroll(MotionEvent e1, MotionEvent e2,

float distanceX, float distanceY) {

if (!isScaling) {

mode = DRAG;

isScaling = false;

horizontalOffset -= distanceX;

verticalOffset -= distanceY;

invalidate(0, 0, screenWidth, screenHeight);

} else {

mode = ZOOM;

isScaling = true;

}

return true;

}

}

@Override

public boolean onTouchEvent(MotionEvent event) {

scaleGesture.onTouchEvent(event);

gestures.onTouchEvent(event);

return true;

}

}

提前致谢。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐