반응형
환경 : 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) 백그라운드에서 Handler 를 통해 UI 변경 (1) | 2014.12.23 |
---|---|
안드로이드(Android) This Handler class should be static or leaks might occur 해결 (6) | 2014.12.21 |
안드로이드(Android) Android.graphics.Color 에서 제공하는 컬러보기 샘플구현 (0) | 2014.12.17 |
안드로이드(Android) Activity 의 라이프사이클(LifeCycle) 알아보기위한 예제 (0) | 2014.12.16 |
안드로이드(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 |