Please Enable JavaScript!
Gon[ Enable JavaScript ]

반응형

안드로이드(Android) SurfaceView Thread 를 이용해여 사각형자동그리기

 

환경 :Eclipse Mars, Android 4.2.2

 

이번예제는 SurfaceView Thread 를 이용해서 사각형이 이동하는 것 같은 그림을 그리게 할 것입니다. Thread 를 이용해 연속적으로 그림을 계속해서 그리게 되는 것이죠. 그림을 그리고 지우는 것이 아니라 배경색을 바꿔서 이전 사각형을 덮어버리기 때문에 이동하는 것 처럼 보이게 되는 것입니다.

 

 

이전 SurfaceView Thread 를 이용해 터치이벤트를 구현한 예제에서 사용한 소스를 조금 손 보았습니다. 먼저 메인 activity 에서 화면의 가로,세로 길이 값을 가져옵니다. 이 두 값의 용도는 사각형이 화면을 벗어나면 다시 처음시작위치에서 그리기 위함입니다.

 

DisplayMetrics disp = getApplicationContext().getResources().getDisplayMetrics();
deviceWidth = disp.widthPixels;
deviceHeight = disp.heightPixels;

 

다음은 SurfaceHolder.Callback,SurfaceView 를 상속받은 사용자 정의 클래스에 대한 것입니다. SurfaceHolder.Callback 상속받았기 때문에 3가지 함수는 필히 구현을 해야 합니다. 생성함수에는 스레드 클래스를 시작하는 코드가 있으며 종료함수에는 스레드를 끝내는 코드가 있습니다.

 

public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}

public void surfaceCreated(SurfaceHolder holder) {
	thread.setRunning(true);
	thread.start();
}

public void surfaceDestroyed(SurfaceHolder holder) {
	boolean retry = true;
	thread.setRunning(false);
	while (retry) {
		try {
			thread.join();
			retry = false;
		} catch (InterruptedException e) {
		}
	}
}

 

마지막으로 스레드 클래스에서 run() 함수입니다. 스레드 객체에서 start() 호출하게 되면 run() 실행된다는 것은 아실거라 생각합니다. 이곳에 Canvas 사각형을 그리는 기능이 있습니다. 화면을 벗어났는지 체크해서 벗어났으면 Left, Top 위치를 초기화 하는 것이죠.

 

@Override
public void run() {
	while (myThreadRun) {
		Canvas c = null;
		try {
			c = mThreadSurfaceHolder.lockCanvas(null);
			synchronized (mThreadSurfaceHolder) {
				Paint mPaint = new Paint();
				mPaint.setColor(Color.WHITE);
				c.drawRect(0, 0, deviceWidth, deviceHeight, mPaint);
				mPaint.setColor(Color.RED);

				c.drawRect(x, x, x - quadWidth, x - quadHeight, mPaint);
				
				x += 5;
				if (x - quadWidth >= deviceWidth) {
					x = 0;
				}
			}
		} finally {
			if (c != null) {
				mThreadSurfaceHolder.unlockCanvasAndPost(c);
			}
		}
	}
}

 

아래는 메인 activity 의 전체 내용입니다. 메인 activity SurfaceView, Thread 클래스가 모두 들어가 있습니다.


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.util.DisplayMetrics;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SurfaceViewRectDrawActivity extends Activity {

	private static int deviceWidth, deviceHeight;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// setContentView(R.layout.activity_surface_view_draw);
		EventSufaceView mySurfaceView = new EventSufaceView(this);
		setContentView(mySurfaceView);
		
		DisplayMetrics disp = getApplicationContext().getResources().getDisplayMetrics();
		deviceWidth = disp.widthPixels;
		deviceHeight = disp.heightPixels;
	}

	public class EventSufaceView extends SurfaceView implements SurfaceHolder.Callback {
	
		private SurfaceThread thread;

		@Override
		public boolean performClick() {
			return super.performClick();
		}
	
		public EventSufaceView(Context context) {
			super(context);
			init();
		}
	
		public EventSufaceView(Context context, AttributeSet attrs) {
			super(context, attrs);
			init();
		}
	
		public EventSufaceView(Context context, AttributeSet attrs, int defStyle) {
			super(context, attrs, defStyle);
			init();
		}
	
		private void init() {
			getHolder().addCallback(this);
			thread = new SurfaceThread(getHolder(), this);
	
			setFocusable(true); // make sure we get key events
		}
	
		public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		}
		
		public void surfaceCreated(SurfaceHolder holder) {
			thread.setRunning(true);
			thread.start();
		}
		
		public void surfaceDestroyed(SurfaceHolder holder) {
			boolean retry = true;
			thread.setRunning(false);
			while (retry) {
				try {
					thread.join();
					retry = false;
				} catch (InterruptedException e) {
				}
			}
		}
	}

	public class SurfaceThread extends Thread {
	
		private SurfaceHolder mThreadSurfaceHolder;
		private EventSufaceView mThreadSurfaceView;
		private boolean myThreadRun = false;
		private int x = 0;
		private int quadWidth = 100;
		private int quadHeight = 100;
		
		public SurfaceThread(SurfaceHolder surfaceHolder, EventSufaceView surfaceView) {
			mThreadSurfaceHolder = surfaceHolder;
			mThreadSurfaceView = surfaceView;
		}
	
		public void setRunning(boolean b) {
			myThreadRun = b;
		}
	
		@Override
		public void run() {
			while (myThreadRun) {
				Canvas c = null;
				try {
					c = mThreadSurfaceHolder.lockCanvas(null);
					synchronized (mThreadSurfaceHolder) {
						Paint mPaint = new Paint();
						mPaint.setColor(Color.WHITE);
						c.drawRect(0, 0, deviceWidth, deviceHeight, mPaint);
						mPaint.setColor(Color.RED);
	
						c.drawRect(x, x, x - quadWidth, x - quadHeight, mPaint);
						
						x += 5;
						if (x - quadWidth >= deviceWidth) {
							x = 0;
						}
					}
				} finally {
					if (c != null) {
						mThreadSurfaceHolder.unlockCanvasAndPost(c);
					}
				}
			}
		}
	}
}

 

 

안드로이드(Android) SurfaceView 와 Thread 를 이용해여 사각형자동그리기

 

반응형
Posted by 녹두장군1
,