Please Enable JavaScript!
Gon[ Enable JavaScript ]

반응형

안드로이드(Android) SurfaceView Thread 이용해 화면에서 움직이는 공구현

 

환경 : Eclipse Mars, Android 4.2.2

 

이번예제는 SurfaceView Thread 클래스를 따로 분리하였으며 SurfaceView 내부에 조그마한 원이 화면끝에 부딪치면 반대편으로 팅겨서 이리저리 움직이는 샘플입니다. 상세 설명은 이전 샘플들을 차근차근 살펴 보시면 될 것 같고 이번에는 간단하게 설명하고 소스만 올리겠습니다.

 

 

메인 activity 의 전체 내용입니다. Xml SurfaceView 를 상속해서 만든 사용자정의 클래스를 객체화하고 버튼위젯들에 대한 이벤트 등록을 합니다.

 

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class AndroidMergeSurfaceView extends Activity {

	GonSurfaceView mySurfaceView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_android_merge_surface);

		mySurfaceView = (GonSurfaceView) findViewById(R.id.myCustomSurface);

		Button buttonShowHide = (Button) findViewById(R.id.showhide);
		final Button buttonDummy = (Button) findViewById(R.id.dummy);

		buttonShowHide.setOnClickListener(new Button.OnClickListener() {
			public void onClick(View arg0) {
				if (buttonDummy.getVisibility() == View.VISIBLE) {
					buttonDummy.setVisibility(View.GONE);
				} else {
					buttonDummy.setVisibility(View.VISIBLE);
				}
			}
		});
	}
}

 

메인 activity xml 파일에 대한 내용입니다. 이번에는 xml SurfaceView 클래스를 직접 등록했습니다.

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/showhide"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="아래 버튼 숨기기/보이기" />

    <Button
        android:id="@+id/dummy"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="버튼 레이아웃" />

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <com.example.samplebooksearchapi.GonSurfaceView
            android:id="@+id/myCustomSurface"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:gravity="bottom"
            android:orientation="vertical" >
           
        </LinearLayout>
    </FrameLayout>

</LinearLayout>

 

SurfaceView 클래스를 상속받아 만든 GonSurfaceView 클래스의 전체 내용입니다. 스레드를 등록하고 관리하는 내용이 들어있습니다.

 

import android.content.Context;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GonSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

	private GonSurfaceThread thread;

	public GonSurfaceView(Context context) {
		super(context);
		init();
	}

	public GonSurfaceView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public GonSurfaceView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	private void init() {
		getHolder().addCallback(this);
		thread = new GonSurfaceThread(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) {
			}
		}
	}
}

 

마지막으로 Thread 에 대한 구현입니다. 핑퐁처럼 이리저리 왔다갔다 하는 모션구현은 Run() 내부에서 이루어 지고 있습니다.

 

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;

public class GonSurfaceThread extends Thread {
	private SurfaceHolder myThreadSurfaceHolder;
	private boolean myThreadRun = false;
	int cx, cy, offx, offy;
	private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
	
	public GonSurfaceThread(SurfaceHolder surfaceHolder, GonSurfaceView surfaceView) {
		myThreadSurfaceHolder = surfaceHolder;
		
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeWidth(3);
		paint.setColor(Color.WHITE);
		
		cx = 0;
		cy = 0;
		offx = 10;
		offy = 10;
	}
	
	public void setRunning(boolean b) {
		myThreadRun = b;
	}

	@Override
	public void run() {
		while(myThreadRun){
			Canvas c = null;

			try{
				c = myThreadSurfaceHolder.lockCanvas(null);
				synchronized (myThreadSurfaceHolder){
					//myThreadSurfaceView.draw(c);
					c.drawRGB(0, 0, 0);
					c.drawCircle(cx, cy, 3, paint);
					cx += offx;
					if (cx > c.getWidth() || (cx < 0)){
						offx *= -1;
						cx += offx;
					}
					
					cy += offy;
					if (cy > c.getHeight() || (cy < 0)){
						offy *= -1;
						cy += offy;
					}
				}
				sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			finally{
				if (c != null) {
					myThreadSurfaceHolder.unlockCanvasAndPost(c);
				}
			}
		}
	}
}

 

 

안드로이드(Android) SurfaceView 와 Thread 이용해 화면에서 움직이는 공구현

 

반응형
Posted by 녹두장군1
,