반응형
|
안드로이드(Android) onDraw() 를 이용해 스크린터치로 원그리기 |
|
환경 : Eclipse Mars, Android 4.2.2 |
이전에는 사용자 개입이 없이 프로그램에서 이미지나 사각형을 그리는 예제 였습니다. 이번에는 사용자의 스크린 터치 이벤트를 감지하여 터치가 이동하는 위치에 따라 원을 그려주는 샘플입니다.
▼ 먼저 View 위젯을 상속받아 사용자정의 클래스를 만듭니다. 그리고 생성자에 원을 그릴 Paint 객체를 셋팅합니다. Paint 객체에 원의 선스타일 굵기등의 값을 넣습니다.
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float initX, initY, radius;
private boolean drawing = false;
public DrawTouchView(Context context) {
super(context);
init();
}
public DrawTouchView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DrawTouchView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(Color.BLACK);
}
▼ 다음은 터치 이벤트 인데 onTouchEvent() 함수를 오버라이딩합니다. 인수로 넘어오는 MotionEvent 객체를 가지고 현재 터치의 형태를 판단합니다. 터지를 움직일 때 ACTION_MOVE 는 현재 포인트 값으로 원을 그리기 위한 지름값을 계산합니다. ACTION_UP 일때는 그리기를 멈춰야 하므로 drawing = false 로 셋팅합니다.
이렇게 이벤트 별로 셋팅이 끝났으면 마지막에 invalidate() 호출하여 현재 화면이 변경되었으니 새로 그리라고 명령을 합니다.
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_MOVE) {
float x = event.getX();
float y = event.getY();
radius = (float) Math.sqrt(Math.pow(x - initX, 2) + Math.pow(y - initY, 2));
} else if (action == MotionEvent.ACTION_DOWN) {
initX = event.getX();
initY = event.getY();
radius = 1;
drawing = true;
} else if (action == MotionEvent.ACTION_UP) {
drawing = false;
performClick();
}
invalidate();
return true;
}
▼ invalidate() 호출하면 View 객체의 onDraw() 함수가 호출되면서 이미지를 계속해서 새로 그리게 되는 것이죠.
@Override
protected void onDraw(Canvas canvas) {
if (drawing) {
canvas.drawCircle(initX, initY, radius, paint);
}
}
▼ 터치이벤트와 조합하여 onDraw 함수에 원을 그리는 Activity 의 소스 전체 내용입니다.
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class DrawTouchActivity extends Activity {
private DrawTouchView mView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_draw_touch);
mView = new DrawTouchView(this);
setContentView(mView);
}
public class DrawTouchView extends View {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float initX, initY, radius;
private boolean drawing = false;
public DrawTouchView(Context context) {
super(context);
init();
}
public DrawTouchView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DrawTouchView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(Color.BLACK);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
if (drawing) {
canvas.drawCircle(initX, initY, radius, paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_MOVE) {
float x = event.getX();
float y = event.getY();
radius = (float) Math.sqrt(Math.pow(x - initX, 2) + Math.pow(y - initY, 2));
} else if (action == MotionEvent.ACTION_DOWN) {
initX = event.getX();
initY = event.getY();
radius = 1;
drawing = true;
} else if (action == MotionEvent.ACTION_UP) {
drawing = false;
performClick();
}
invalidate();
return true;
}
@Override
public boolean performClick() {
return super.performClick();
}
}
}
반응형
'안드로이드 개발' 카테고리의 다른 글
| 안드로이드(Android) SurfaceView 와 Thread 를 이용해여 사각형자동그리기 (0) | 2014.12.09 |
|---|---|
| 안드로이드(Android) getWidth() from the type Display is deprecated 수정 (0) | 2014.12.02 |
| 안드로이드(Android) SurfaceView 와 Thread 를 이용해 화면에 도형표현 하기 (0) | 2014.12.01 |
| 안드로이드(Android) 두개의 사용자정의 View 를 FrameLayout 으로 표현하기 (0) | 2014.11.30 |
| 안드로이드(Android) 경고 - Custom view… overrides onTouchEvent but not performClick (0) | 2014.11.28 |
| 안드로이드(Android) onDraw 함수를 이용해 화면에 비트맵이미지, 도형 그리기 (0) | 2014.11.27 |
| 안드로이드(Android) 코드경고 – Avoid object allocations during draw/layout operations (preallocate and reuse instead) 해제 하기 (0) | 2014.11.26 |
| 안드로이드(Android) RSS 구현5 - RSS 제목별 상세내용 구현 (1) | 2014.11.25 |
