안드로이드 개발 질문/답변
(글 수 45,052)
package android.ajou.amicom;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class Dot extends View{
private static final float RADIUS = 10;
private float x = 30;
private float y = 30;
private float initialX;
private float initialY;
private float offsetX;
private float offsetY;
private Paint backgroundPaint;
private Paint myPaint;
public Dot(Context context, AttributeSet attrs){
super(context, attrs);
backgroundPaint = new Paint();
backgroundPaint.setColor(Color.WHITE);
myPaint = new Paint();
myPaint.setColor(Color.BLACK);
myPaint.setAntiAlias(true);
}
@Override
public boolean onTouchEvent(MotionEvent event){
int action = event.getAction();
switch(action) {
case MotionEvent.ACTION_DOWN:
if(event.getAction() == MotionEvent.ACTION_DOWN) {
initialX = x;
initialY = y;
offsetX = event.getX();
offsetY = event.getY();
int X = (int)event.getX();
int Y = (int)event.getY();
if(Math.pow( X - x, 2) + Math.pow( Y - y, 2) <= Math.pow(10, 2))
}
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
x = initialX + event.getX() - offsetX;
y = initialY + event.getY() - offsetY;
break;
}
event.recycle();
return(true);
}
@Override
public void draw(Canvas canvas){
int width = canvas.getWidth();
int height = canvas.getHeight();
canvas.drawRect(0, 0, width, height, backgroundPaint);
canvas.drawCircle(x, y, RADIUS, myPaint);
invalidate();
}
}
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class Dot extends View{
private static final float RADIUS = 10;
private float x = 30;
private float y = 30;
private float initialX;
private float initialY;
private float offsetX;
private float offsetY;
private Paint backgroundPaint;
private Paint myPaint;
public Dot(Context context, AttributeSet attrs){
super(context, attrs);
backgroundPaint = new Paint();
backgroundPaint.setColor(Color.WHITE);
myPaint = new Paint();
myPaint.setColor(Color.BLACK);
myPaint.setAntiAlias(true);
}
@Override
public boolean onTouchEvent(MotionEvent event){
int action = event.getAction();
switch(action) {
case MotionEvent.ACTION_DOWN:
if(event.getAction() == MotionEvent.ACTION_DOWN) {
initialX = x;
initialY = y;
offsetX = event.getX();
offsetY = event.getY();
int X = (int)event.getX();
int Y = (int)event.getY();
if(Math.pow( X - x, 2) + Math.pow( Y - y, 2) <= Math.pow(10, 2))
}
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
x = initialX + event.getX() - offsetX;
y = initialY + event.getY() - offsetY;
break;
}
event.recycle();
return(true);
}
@Override
public void draw(Canvas canvas){
int width = canvas.getWidth();
int height = canvas.getHeight();
canvas.drawRect(0, 0, width, height, backgroundPaint);
canvas.drawCircle(x, y, RADIUS, myPaint);
invalidate();
}
}
원을 만들고 원을 터치와 드래그 시키는 코드 입니다.
ACTION_DOWN에서 원 밖의 영역에서는 터치가 되지 않도록 하고 싶어서 if문을 넣어봤는데요.
아무리봐도 뭐가 좀 많이 안맞는거 같아요.
X,Y는 원의 좌표로 하고 x,y는 마우스 클릭위치로 해서 그 길이를 통해 영역설정을 하고 싶은데요.
틀린거좀 고쳐주세요.
자바 완전 초보라서 혼자라기 힘들거든요 ㅜㅜ 부탁드려요~
2011.07.18 23:52:20
원을 터치 했을 때만 코드로 나타내 봤습니다.
private static final float RADIUS = 10.0f;
private static final int STATE_NONE = 0;
private static final int STATE_DRAG = 1;
private int mState = STATE_NONE;
private float mX = 30.0f;
private float mY = 30.0f;
@Override
public boolean onTouchEvent(MotionEvent event){
switch (event.getAction) {
case MotionEvent.ACTION_DOWN:
final float x = event.getX();
final float y = event.getY();
if (Math.sqrt(Math.pow(x - mX, 2) + Math.pow(y - mY, 2)) <= RADIUS) {
// 루트((터치X - x)^2 + (터치Y - y)^2) < RADIUS
mState = STATE_DRAG;
}
return true;
}
}




draw()를 오버라이드 하셨네요 draw() 보다는 onDraw를 오버라이드 하시고 그리는 메서드안에서는 invalidate를 하시면 안됩니다.
순서로 풀어보자면 대충 이런 과정이겠군요 중요한 점은 그림은 x, y 좌표를 저장한 상태를 토데로 그리는것이며 터치 이벤트에서는 상태가 변경할 상황이면 변경해주면 된다는 겁니다.
1. onTouchEvent의 ACTION_DOWN이 일어나면 원안인지 아닌지 확인한다. (원의 중심을 mX, mY라고 했을 때 피타고라스의 정리에 의해 터치한 영역과의 거리가 원의 반지름보다 작은 위치에 있다면 원을 클릭한게 되겠죠) 만약 원안이라면 별도의 플래그를 두어 원이 드래그 할 수 있게 되었음을 상태를 변경해준다.
2. onTouchEvent의 ACTION_MOVE에서는 플래그값이 드래그상태라면 드래그한만큼의 x, y 좌표의 offset 값을 추적하여 원의 현재 위치를 업데이트 시켜준다. 그리고 업데이트 시킨값을 토데로 다시 그릴 수 있도록 invalidate()를 호출해 캔버스를 새로그린다.
3. 원의 상태 플래그가 드래그 상태일때 onTouchEvent의 ACTION_UP이 일어나면 드래그가 멈추었기때문에 플래그값을 원래대로 바꿔준다.