アンドロイドのタッチイベントで長方形を描く方法。キャンバスをタッチすると長方形が描画されますが、新しい場所をタッチすると古い長方形が削除され、新しい場所に新しい長方形が描画されます。しかし、私は触れた場所にすべての長方形を表示したままにしておきたいです。
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;
boolean isCheckLoadImage = false;
public static boolean isDraw = false;
int mode = NONE;
private float mPosX;
private float mPosY;
public static int numCell1 = 0;
public static boolean CorrectTouch;
float boxHeight, boxWidth;
// Remember some things for zooming
PointF last = new PointF();
PointF start = new PointF();
float minScale = 1f;
float maxScale = 6f;
int lastTouchEvent = -1;
int selectedCell;
float[] m;
float scaleWidth, scaleHeight;
float redundantXSpace, redundantYSpace;
float width, height;
static final int CLICK = 3;
float saveScale = 1f;
float right, bottom, origWidth, origHeight, bmWidth, bmHeight;
ScaleGestureDetector mScaleDetector;
Context context;
boolean flag = false;
public TouchImageView(Context context) {
super(context);
sharedConstructing(context);
}
public TouchImageView(Context context, AttributeSet attrs) {
super(context, attrs);
sharedConstructing(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4);
RectF r = new RectF();
matrix.mapRect(r);
boxWidth = scaleWidth / 5;
boxHeight = scaleHeight / 5;
float widthOfCell = boxWidth;
float heightOfCell = boxHeight;
float[] touchPoint = new float[] { mPosX, mPosY };
float[] newTouch = new float[] { 0, 0 };
matrix.mapPoints(newTouch, touchPoint);
RectF canvasRect = new RectF();
canvas.getMatrix().mapRect(canvasRect);
Log.i("canvasRect", "canvasRect.left : " + canvasRect.left
+ " canvasRect.top : " + canvasRect.top);
Log.i("r", "r.left : " + r.left + " r.top : " + r.top);
Log.i("Pos", "mPosX : " + mPosX + " mPosY : " + mPosY);
float newX = mPosX - (r.left);
float newY = mPosY - (r.top);
Log.i("new XY", "New X" + newX + " NewY " + newY);
int myX = (int) (newX / boxWidth); /* Columns */
int myY = (int) (newY / boxHeight);/* Rows */
Log.i("my XY", "myX " + myX + " myY " + myY);
//
Log.e("GuessImageView", "before grid draw");
try {
if (true) {
if (lastTouchEvent == MotionEvent.ACTION_UP) {
numCell1 = 0;
boolean doBreak = false;
for (float row = 0; !doBreak
&& row <5; row++) {
float y = (row * heightOfCell) + r.top;
for (float col = 0; col < 5; col++) {
float x = (col * widthOfCell) + r.left;
if ((int) col == myX && (int) row == myY) {
canvas.drawRect(x, y, x + widthOfCell, y
+ heightOfCell, paint);
Log.d("Touch X : " + x, "Touch Y : " + y);
selectedCell = numCell1;
numCell1++;
flag = true;
doBreak = true;
break;
}
numCell1++;
}
}
if (flag) {
isCheckLoadImage = true;
// guessImage.checkForWin(selectedCell);
}
Log.i("Touch ", "Number Of Cell>" + numCell1);
lastTouchEvent = -1;
}
}
} catch (ArithmeticException e) {
e.printStackTrace();
}
Log.e("GuessImageView", "after grid draw");
}
private void sharedConstructing(Context context) {
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) {
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;
// isDraw=false;
break;
case MotionEvent.ACTION_MOVE:
// Log.i("onTouch", "origWidth : " + origWidth +
// " origHeight : " + origHeight);
if (mode == DRAG) {
// isDraw=false;
float deltaX = curr.x - last.x;
float deltaY = curr.y - last.y;
scaleWidth = Math.round(origWidth * saveScale);
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) {
// isDraw=false;
Log.v("ACTION_UP", "ACTION_UP");
mPosX = curr.x;
mPosY = curr.y;
performClick();
// if (guessImage.guess_mode) {
lastTouchEvent = event.getAction();
/*}
else {
lastTouchEvent = -1;
}
*/
// invalidate();
}
break;
}
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
}
setImageMatrix(matrix);
scaleWidth = Math.round(origWidth * saveScale);
scaleHeight = Math.round(origHeight * saveScale);
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;
}
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);
// mPosX = mPosX + right / saveScale;
// mPosY = mPosY + bottom / saveScale;
if (origWidth * saveScale <= width
|| origHeight * saveScale <= height) {
float xMove = 0, yMove = 0;
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));
xMove = 0;
yMove = -(y + bottom);
} else if (y > 0) {
matrix.postTranslate(0, -y);
xMove = 0;
yMove = -y;
}
} else {
if (x < -right) {
matrix.postTranslate(-(x + right), 0);
xMove = -(x + right);
yMove = 0;
} else if (x > 0) {
matrix.postTranslate(-x, 0);
xMove = -(x + right);
yMove = 0;
}
}
Log.i("onScale", "mPosX " + mPosX + " mPosX " + mPosX);
}
}
} else {
float xMove = 0, yMove = 0;
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);
xMove = -(x + right);
yMove = 0;
} else if (x > 0) {
matrix.postTranslate(-x, 0);
xMove = -x;
yMove = 0;
}
if (y < -bottom) {
matrix.postTranslate(0, -(y + bottom));
xMove = 0;
yMove = -(y + bottom);
} else if (y > 0) {
matrix.postTranslate(0, -y);
xMove = 0;
yMove = -y;
}
}
Log.i("onScale", "mPosX " + mPosX + " mPosX " + mPosX);
}
return true;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!isCheckLoadImage) {
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
// Fit to screen.
float scale;
float scaleX = (float) width / (float) bmWidth;
float scaleY = (float) height / (float) bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
setImageMatrix(matrix);
saveScale = 1f;
// Center the image
redundantYSpace = (float) height - (scale * (float) bmHeight);
redundantXSpace = (float) width - (scale * (float) bmWidth);
redundantYSpace /= (float) 2;
redundantXSpace /= (float) 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);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}