我正在开发一个应用程序,其流程如下:-
1 :- User will pick image from app Gallery which a grid view after that draw selected image on view as a overlay ,This View has background image as well.
2 :- Now There are two button in above view one for background zoom and second for overlay zoom and drag(drag is not applicable in background).
3 :- If user click button zoom for background then overlay will not drag or zoom vice versa.
**Problem** My problem is that above functionality not work any one guide me
提前致谢。我的代码如下: -
protected void onSizeChanged(int width, int height, int oldWidth,
int oldHeight) {
super.onSizeChanged(width, height, oldWidth, oldHeight);
containerWidth = width;
containerHeight = height;
if (imgBitmap != null) {
int imgHeight = imgBitmap.getHeight();
int imgWidth = imgBitmap.getWidth();
float scale;
int initX = 0;
int initY = 0;
if (defaultScale == ZoomableImage.DEFAULT_SCALE_FIT_INSIDE) {
if (imgWidth > containerWidth) {
scale = (float) containerWidth / imgWidth;
float newHeight = imgHeight * scale;
initY = (containerHeight - (int) newHeight) / 2;
matrix.setScale(scale, scale);
matrix.postTranslate(0, initY);
} else {
scale = (float) containerHeight / imgHeight;
float newWidth = imgWidth * scale;
initX = (containerWidth - (int) newWidth) / 2;
matrix.setScale(scale, scale);
matrix.postTranslate(initX, 0);
}
curX = initX;
curY = initY;
currentScale = scale;
minScale = scale;
} else {
if (imgWidth > containerWidth) {
initY = (containerHeight - (int) imgHeight) / 2;
matrix.postTranslate(0, initY);
} else {
initX = (containerWidth - (int) imgWidth) / 2;
matrix.postTranslate(initX, 0);
}
curX = initX;
curY = initY;
currentScale = 1.0f;
minScale = 1.0f;
}
invalidate();
}
if (overlayBitmap != null) {
int imgHeight = overlayBitmap.getHeight();
int imgWidth = overlayBitmap.getWidth();
float scale;
int initX = 0;
int initY = 0;
if (overlaydefaultScale == ZoomableImage.DEFAULT_OVERLAY_SCALE_FIT_INSIDE) {
if (imgWidth > overlaycontainerWidth) {
scale = (float) overlaycontainerWidth / imgWidth;
float newHeight = imgHeight * scale;
initY = (containerHeight - (int) newHeight) / 2;
overlaymatrix.setScale(scale, scale);
overlaymatrix.postTranslate(0, initY);
} else {
scale = (float) overlaycontainerHeight / imgHeight;
float newWidth = imgWidth * scale;
initX = (overlaycontainerWidth - (int) newWidth) / 2;
overlaymatrix.setScale(scale, scale);
overlaymatrix.postTranslate(initX, 0);
}
overlaycurX = initX;
overlaycurY = initY;
overlaycurrentScale = scale;
overlayminScale = scale;
} else {
if (imgWidth > overlaycontainerWidth) {
initY = (overlaycontainerHeight - (int) imgHeight) / 2;
overlaymatrix.postTranslate(0, initY);
} else {
initX = (overlaycontainerWidth - (int) imgWidth) / 2;
overlaymatrix.postTranslate(initX, 0);
}
overlaycurX = initX;
overlaycurY = initY;
overlaycurrentScale = 1.0f;
overlayminScale = 1.0f;
}
invalidate();
}
}
private Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1,matrix,null);
canvas.drawBitmap(bmp2,overlaymatrix, overlayPaint);
return bmOverlay;
}
@Override
protected void onDraw(Canvas canvas) {
if (bitmapback != null && canvas != null && overlayBitmap != null && canvas != null) {
Bitmap objbm = overlay(bitmapback,overlayBitmap);
canvas.drawBitmap(objbm,0,0,null);
//caas.drawBitmap(overlayBitmap,overlaymatrix, overlayPaint);
}
super.onDraw(canvas);
}
private void checkImageConstraints() {
if (imgBitmap == null) {
return;
}
float[] mvals = new float[9];
matrix.getValues(mvals);
currentScale = mvals[0];
if (currentScale < minScale) {
float deltaScale = minScale / currentScale;
float px = containerWidth / 2;
float py = containerHeight / 2;
matrix.postScale(deltaScale, deltaScale, px, py);
invalidate();
}
matrix.getValues(mvals);
currentScale = mvals[0];
curX = mvals[2];
curY = mvals[5];
int rangeLimitX = containerWidth
- (int) (imgBitmap.getWidth() * currentScale);
int rangeLimitY = containerHeight
- (int) (imgBitmap.getHeight() * currentScale);
boolean toMoveX = false;
boolean toMoveY = false;
if (rangeLimitX < 0) {
if (curX > 0) {
targetX = 0;
toMoveX = true;
} else if (curX < rangeLimitX) {
targetX = rangeLimitX;
toMoveX = true;
}
} else {
targetX = rangeLimitX / 2;
toMoveX = true;
}
if (rangeLimitY < 0) {
if (curY > 0) {
targetY = 0;
toMoveY = true;
} else if (curY < rangeLimitY) {
targetY = rangeLimitY;
toMoveY = true;
}
} else {
targetY = rangeLimitY / 2;
toMoveY = true;
}
if (toMoveX == true || toMoveY == true) {
if (toMoveY == false) {
targetY = curY;
}
if (toMoveX == false) {
targetX = curX;
}
isAnimating = true;
mHandler.removeCallbacks(mUpdateImagePositionTask);
mHandler.postDelayed(mUpdateImagePositionTask, 100);
}
}
hecks and sets the target image x and y co-ordinates if out of bounds
private void checkOverlayImageConstraints() {
if (overlayBitmap == null) {
return;
}
float[] mvals = new float[9];
overlaymatrix.getValues(mvals);
overlaycurrentScale = mvals[0];
if (overlaycurrentScale < overlayminScale) {
float deltaScale = overlayminScale / overlaycurrentScale;
float px = overlaycontainerWidth / 2;
float py = overlaycontainerHeight / 2;
overlaymatrix.postScale(deltaScale, deltaScale, px, py);
invalidate();
}
overlaymatrix.getValues(mvals);
overlaycurrentScale = mvals[0];
overlaycurX = mvals[2];
overlaycurY = mvals[5];
int rangeLimitX = overlaycontainerWidth
- (int) (overlayBitmap.getWidth() * overlaycurrentScale);
int rangeLimitY = overlaycontainerHeight
- (int) (overlayBitmap.getHeight() * overlaycurrentScale);
boolean toMoveX = false;
boolean toMoveY = false;
if (rangeLimitX < 0) {
if (overlaycurX > 0) {
overlaytargetX = 0;
toMoveX = true;
} else if (overlaycurX < rangeLimitX) {
overlaytargetX = rangeLimitX;
toMoveX = true;
}
} else {
overlaytargetX = rangeLimitX / 2;
toMoveX = true;
}
if (rangeLimitY < 0) {
if (overlaycurY > 0) {
overlaytargetY = 0;
toMoveY = true;
} else if (overlaycurY < rangeLimitY) {
overlaytargetY = rangeLimitY;
toMoveY = true;
}
} else {
overlaytargetY = rangeLimitY / 2;
toMoveY = true;
}
if (toMoveX == true || toMoveY == true) {
if (toMoveY == false) {
overlaytargetY = overlaycurY;
}
if (toMoveX == false) {
overlaytargetX = overlaycurX;
}
isoverlayAnimating = true;
overlaymHandler.removeCallbacks(mOverlayUpdateImagePositionTask);
overlaymHandler.postDelayed(mOverlayUpdateImagePositionTask, 100);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!AppConstant.isBackZom) {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
if (isAnimating == true) {
return true;
}
float[] mvals = new float[9];
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if (isAnimating == false) {
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
matrix.getValues(mvals);
curX = mvals[2];
curY = mvals[5];
currentScale = mvals[0];
if (isAnimating == false) {
checkImageConstraints();
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG && isAnimating == false) {
matrix.set(savedMatrix);
float diffX = event.getX() - start.x;
float diffY = event.getY() - start.y;
matrix.postTranslate(diffX, diffY);
matrix.getValues(mvals);
curX = mvals[2];
curY = mvals[5];
currentScale = mvals[0];
} else if (mode == ZOOM && isAnimating == false) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.getValues(mvals);
currentScale = mvals[0];
if (currentScale * scale <= minScale) {
matrix.postScale(minScale / currentScale, minScale
/ currentScale, mid.x, mid.y);
} else if (currentScale * scale >= maxScale) {
matrix.postScale(maxScale / currentScale, maxScale
/ currentScale, mid.x, mid.y);
} else {
matrix.postScale(scale, scale, mid.x, mid.y);
}
matrix.getValues(mvals);
curX = mvals[2];
curY = mvals[5];
currentScale = mvals[0];
}
}
break;
}
invalidate();
} else {
if (gestureDetector.onTouchEvent(event)) {
return true;
}
if (isoverlayAnimating == true) {
return true;
}
float[] mvals = new float[9];
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
if (isoverlayAnimating == false) {
overlaysavedMatrix.set(overlaymatrix);
overlaystart.set(event.getX(), event.getY());
overlaymode = OVERLAY_DRAG;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
overlayoldDist = spacing(event);
if (overlayoldDist > 10f) {
overlaysavedMatrix.set(matrix);
midPoint(overlaymid, event);
overlaymode = OVERLAY_ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
overlaymode = OVERLAY_NONE;
overlaymatrix.getValues(mvals);
overlaycurX = mvals[2];
overlaycurY = mvals[5];
overlaycurrentScale = mvals[0];
if (isoverlayAnimating == false) {
checkOverlayImageConstraints();
}
break;
case MotionEvent.ACTION_MOVE:
if (overlaymode == OVERLAY_DRAG && isoverlayAnimating == false) {
matrix.set(savedMatrix);
float diffX = event.getX() - overlaystart.x;
float diffY = event.getY() - overlaystart.y;
overlaymatrix.postTranslate(diffX, diffY);
overlaymatrix.getValues(mvals);
overlaycurX = mvals[2];
overlaycurY = mvals[5];
overlaycurrentScale = mvals[0];
} else if (overlaymode == OVERLAY_ZOOM && isoverlayAnimating == false) {
float newDist = spacing(event);
if (newDist > 10f) {
overlaymatrix.set(overlaysavedMatrix);
float scale = newDist / overlayoldDist;
overlaymatrix.getValues(mvals);
overlaycurrentScale = mvals[0];
if (overlaycurrentScale * scale <= overlayminScale) {
overlaymatrix.postScale(overlayminScale / overlaycurrentScale, overlayminScale
/ overlaycurrentScale, overlaymid.x, overlaymid.y);
} else if (overlaycurrentScale * scale >= overlaymaxScale) {
overlaymatrix.postScale(overlaymaxScale / overlaycurrentScale, overlaymaxScale
/ overlaycurrentScale, overlaymid.x, overlaymid.y);
} else {
overlaymatrix.postScale(scale, scale, overlaymid.x, overlaymid.y);
}
overlaymatrix.getValues(mvals);
overlaycurX = mvals[2];
overlaycurY = mvals[5];
overlaycurrentScale = mvals[0];
}
}
break;
}
invalidate();
}
return true;
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
public void setImageBitmap(Bitmap b) {
if (b != null) {
imgBitmap = b;
containerWidth = getWidth();
containerHeight = getHeight();
int imgHeight = imgBitmap.getHeight();
int imgWidth = imgBitmap.getWidth();
float scale;
int initX = 0;
int initY = 0;
matrix.reset();
if (defaultScale == ZoomableImage.DEFAULT_SCALE_FIT_INSIDE) {
if (imgWidth > containerWidth) {
scale = (float) containerWidth / imgWidth;
float newHeight = imgHeight * scale;
initY = (containerHeight - (int) newHeight) / 2;
matrix.setScale(scale, scale);
matrix.postTranslate(0, initY);
} else {
scale = (float) containerHeight / imgHeight;
float newWidth = imgWidth * scale;
initX = (containerWidth - (int) newWidth) / 2;
matrix.setScale(scale, scale);
matrix.postTranslate(initX, 0);
}
curX = initX;
curY = initY;
currentScale = scale;
minScale = scale;
} else {
if (imgWidth > containerWidth) {
initX = 0;
if (imgHeight > containerHeight) {
initY = 0;
} else {
initY = (containerHeight - (int) imgHeight) / 2;
}
matrix.postTranslate(0, initY);
} else {
initX = (containerWidth - (int) imgWidth) / 2;
if (imgHeight > containerHeight) {
initY = 0;
} else {
initY = (containerHeight - (int) imgHeight) / 2;
}
matrix.postTranslate(initX, 0);
}
curX = initX;
curY = initY;
currentScale = 1.0f;
minScale = 1.0f;
}
invalidate();
} else {
Log.d(TAG, "bitmap is null");
}
}
public void setOverlayImageBitmap(Bitmap b) {
if (b != null) {
overlayBitmap = b;
overlaycontainerWidth = getWidth();
overlaycontainerHeight = getHeight();
int imgHeight = overlayBitmap.getHeight();
int imgWidth = overlayBitmap.getWidth();
float scale;
int initX = 0;
int initY = 0;
overlaymatrix.reset();
if (overlaydefaultScale == ZoomableImage.DEFAULT_OVERLAY_SCALE_FIT_INSIDE) {
if (imgWidth > overlaycontainerWidth) {
scale = (float) overlaycontainerWidth / imgWidth;
float newHeight = imgHeight * scale;
initY = (overlaycontainerHeight - (int) newHeight) / 2;
overlaymatrix.setScale(scale, scale);
overlaymatrix.postTranslate(0, initY);
} else {
scale = (float) overlaycontainerHeight / imgHeight;
float newWidth = imgWidth * scale;
initX = (overlaycontainerWidth - (int) newWidth) / 2;
overlaymatrix.setScale(scale, scale);
overlaymatrix.postTranslate(initX, 0);
}
overlaycurX = initX;
overlaycurY = initY;
overlaycurrentScale = scale;
overlayminScale = scale;
} else {
if (imgWidth > overlaycontainerWidth) {
initX = 0;
if (imgHeight > overlaycontainerHeight) {
initY = 0;
} else {
initY = (overlaycontainerHeight - (int) imgHeight) / 2;
}
overlaymatrix.postTranslate(0, initY);
} else {
initX = (overlaycontainerWidth - (int) imgWidth) / 2;
if (imgHeight > overlaycontainerHeight) {
initY = 0;
} else {
initY = (overlaycontainerHeight - (int) imgHeight) / 2;
}
overlaymatrix.postTranslate(initX, 0);
}
overlaycurX = initX;
overlaycurY = initY;
overlaycurrentScale = 1.0f;
overlayminScale = 1.0f;
}
invalidate();
} else {
Log.d(TAG, "bitmap is null");
}
}
private Runnable mUpdateImagePositionTask = new Runnable() {
public void run() {
float[] mvals;
if (Math.abs(targetX - curX) < 5 && Math.abs(targetY - curY) < 5) {
isAnimating = false;
mHandler.removeCallbacks(mUpdateImagePositionTask);
mvals = new float[9];
matrix.getValues(mvals);
currentScale = mvals[0];
curX = mvals[2];
curY = mvals[5];
float diffX = (targetX - curX);
float diffY = (targetY - curY);
matrix.postTranslate(diffX, diffY);
} else {
isAnimating = true;
mvals = new float[9];
matrix.getValues(mvals);
currentScale = mvals[0];
curX = mvals[2];
curY = mvals[5];
float diffX = (targetX - curX) * 0.3f;
float diffY = (targetY - curY) * 0.3f;
matrix.postTranslate(diffX, diffY);
mHandler.postDelayed(this, 25);
}
invalidate();
}
};
private Runnable mOverlayUpdateImagePositionTask = new Runnable() {
public void run() {
float[] mvals;
if (Math.abs(overlaytargetX - overlaycurX) < 5 && Math.abs(overlaytargetY - overlaycurY) < 5) {
isoverlayAnimating = false;
overlaymHandler.removeCallbacks(mOverlayUpdateImagePositionTask);
mvals = new float[9];
overlaymatrix.getValues(mvals);
overlaycurrentScale = mvals[0];
overlaycurX = mvals[2];
overlaycurY = mvals[5];
float diffX = (overlaytargetX - overlaycurX);
float diffY = (overlaytargetY - overlaycurY);
overlaymatrix.postTranslate(diffX, diffY);
} else {
isoverlayAnimating = true;
mvals = new float[9];
overlaymatrix.getValues(mvals);
overlaycurrentScale = mvals[0];
overlaycurX = mvals[2];
overlaycurY = mvals[5];
float diffX = (overlaytargetX - overlaycurX) * 0.3f;
float diffY = (overlaytargetY - overlaycurY) * 0.3f;
overlaymatrix.postTranslate(diffX, diffY);
overlaymHandler.postDelayed(this, 25);
}
invalidate();
}
};
**Here are 2 function of gesture but write only 1 due charactre ***
private Runnable mUpdateImageScale = new Runnable() {
public void run() {
float transitionalRatio = targetScale / currentScale;
float dx;
if (Math.abs(transitionalRatio - 1) > 0.05) {
isAnimating = true;
if (targetScale > currentScale) {
dx = transitionalRatio - 1;
scaleChange = 1 + dx * 0.2f;
currentScale *= scaleChange;
if (currentScale > targetScale) {
currentScale = currentScale / scaleChange;
scaleChange = 1;
}
} else {
dx = 1 - transitionalRatio;
scaleChange = 1 - dx * 0.5f;
currentScale *= scaleChange;
if (currentScale < targetScale) {
currentScale = currentScale / scaleChange;
scaleChange = 1;
}
}
if (scaleChange != 1) {
matrix.postScale(scaleChange, scaleChange, targetScaleX,
targetScaleY);
mHandler.postDelayed(mUpdateImageScale, 15);
invalidate();
} else {
isAnimating = false;
scaleChange = 1;
matrix.postScale(targetScale / currentScale, targetScale
/ currentScale, targetScaleX, targetScaleY);
currentScale = targetScale;
mHandler.removeCallbacks(mUpdateImageScale);
invalidate();
checkImageConstraints();
}
} else {
isAnimating = false;
scaleChange = 1;
matrix.postScale(targetScale / currentScale, targetScale
/ currentScale, targetScaleX, targetScaleY);
currentScale = targetScale;
mHandler.removeCallbacks(mUpdateImageScale);
invalidate();
checkImageConstraints();
}
}
};
private void dumpEvent(MotionEvent event) {
String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
}
**Here are 2 function of gesture but write only 1 due charactre ***
class GestureOverlayDetector extends SimpleOnGestureListener {
@Override
public boolean onDoubleTap(MotionEvent event) {
if (isoverlayAnimating == true) {
return true;
}
overlayscaleChange = 1;
isoverlayAnimating = true;
overlaytargetScaleX = event.getX();
overlaytargetScaleY = event.getY();
if (Math.abs(overlaycurrentScale - overlaymaxScale) > 0.1) {
overlaytargetScale = overlaymaxScale;
} else {
overlaytargetScale = overlayminScale;
}
overlaytargetRatio = overlaytargetScale / overlaycurrentScale;
overlaymHandler.removeCallbacks(moverlayUpdateImageScale);
overlaymHandler.post(moverlayUpdateImageScale);
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
}
}
在这里,我编写了我的代码,其中位图 1 的 no 是背景,其他的是叠加,而不是同时绘制。拖动也没有处理,请任何人在我错的地方看到这段代码。