Please Enable JavaScript!
Gon[ Enable JavaScript ]

안드로이드(Android) onDraw() 를 이용해 스크린터치로 원그리기

안드로이드 개발
반응형

안드로이드(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) onDraw() 를 이용해 스크린터치로 원그리기

반응형
Posted by 녹두장군1
,