drawArc + Thread 원 그리기

Posted by ITPangPang
2017.01.19 22:34 분류없음


drawArc + Thread

 원 그리기


이번글은 지난글 마지막에 말했던 drawArc와

    Thread를 이용해서 실시간 원을 그리는 방법에 대해

    알아보도록 하겠습니다.


ㆍ drawArc 사용방법은 지난글에서 알아보았으니

    간단하게 코드위주로 보고 끝내도록 하겠습니다.




간단하게 위에 처럼 만들어보겠습니다.


원리만 알면

쉽게 컨츄럴 해서 다양하게

사용 가능합니다



바로 시작해보겠습니다

(이전글 안보신분들은 꼭 보시길!!)


canvas.drawArc(rect, 270, i, false, pnt);


이 부분만 잘 보면 되겠죠?


270도가 시작지점이고,

i위치가 몇도를 돌릴것인지 결정하므로

i에 1을 넣게 되면 270도에서 271도까지 돌리는거겠죠?

그 다음 i에 2를 넣게 되면 270도에서 272도까지 돌리는거겠죠?


자 그럼 Thread를 돌려서

n초 마다 i값을 증가시켜주면

간단하게 끝납니다.



코드를 보겠습니다.


먼저,

앱을 실행하면

바로 서브스레드를

실행시킵니다.

MyView myView;
Thread myThread;
MyRunnable myRunnable;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView = (MyView)findViewById(R.id.myView);
startSubThread();
}
public void startSubThread()
{
myRunnable = new MyRunnable();
myThread = new Thread(myRunnable);
myThread.setDaemon(true);
myThread.start();
}




그 다음

Handler와 Runnable을 보면

android.os.Handler mainHandler = new android.os.Handler()
{
public void handleMessage(Message msg)
{
if (msg.what == 0)
{
myView.invalidate();
}
}
};


public class MyRunnable implements Runnable
{
@Override
public void run()
{
while(mainHandler!=null)
{
try
{
myView.i = myView.i + 0.6f;
Message msg = Message.obtain();
msg.what = 0;
mainHandler.sendMessage(msg);
}
catch (Exception e)
{
e.printStackTrace();
}

try
{
Thread.sleep(10);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}


myView.i = myView.i + 0.6f;

drawArc 들어가는 i값을 0.6씩 증가시킵니다


Thread.sleep(10);

1000이 1초이므로 0.01초마다 증가하겠죠?


myView.invalidate();

0.01초마다 invalidate() 해줍니다.

invalidate()를 써주면 커스텀뷰의

onDraw()가 실행됩니다.



그 다음은 MyView를 볼까요?

@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint pnt = new Paint();
pnt.setStrokeWidth(6f);
pnt.setColor(Color.parseColor("#FF0000"));
pnt.setStyle(Paint.Style.STROKE);

RectF rect = new RectF();
rect.set(200, (200), 600, 600);
canvas.drawArc(rect, 270, i, false, pnt);
}

이 부분이 0.01초마다 호출되는 부분입니다.


canvas.drawArc(rect, 270ifalse, pnt);


i값이 0.01초마다 0.6씩 증가합니다.


자 이렇게 되면 

270 -> 270.6

270 -> 271.2

270 -> 271.8

270 -> 272.4

이런식으로 엄청 빠르게 진행되겠죠?



자 그럼 만약 반시계반향으로

진행하려면 어떻게 할까요?


써보면서 생각하면 쉽습니다.

269.4 -> 270

268.8 -> 270

268.6 -> 270

이런식으로 drawArc가 시계반향으로

진행되므로 끝점인 270은 고정시키고

시작점을 아에 0.6씩 빼버리면 되겠죠?


canvas.drawArc(rect, (270-i), i, false, pnt);


이렇게 써 넣으면 되겠죠?


그럼 전체 코드를 보면서 마무리 하겠습니다.

(코드는 정리하고 수정해서 쓰세요 ㅎㅎ

너무 대충 짜서 .ㅠㅠ)


[MainActivity]

public class MainActivity extends AppCompatActivity
{
MyView myView;
Thread myThread;
MyRunnable myRunnable;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myView = (MyView)findViewById(R.id.myView);
startSubThread();
}
public void startSubThread()
{
myRunnable = new MyRunnable();
myThread = new Thread(myRunnable);
myThread.setDaemon(true);
myThread.start();
}

android.os.Handler mainHandler = new android.os.Handler()
{
public void handleMessage(Message msg)
{
if (msg.what == 0)
{
myView.invalidate();
}
}
};


public class MyRunnable implements Runnable
{
@Override
public void run()
{
while(mainHandler!=null)
{
try
{
myView.i = myView.i + 0.6f;
Message msg = Message.obtain();
msg.what = 0;
mainHandler.sendMessage(msg);
}
catch (Exception e)
{
e.printStackTrace();
}

try
{
Thread.sleep(10);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}


[MyView]

public class MyView extends View
{
float i;
public MyView(Context context, AttributeSet attrs)
{
super(context, attrs);
}

@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint pnt = new Paint();
pnt.setStrokeWidth(6f);
pnt.setColor(Color.parseColor("#FF0000"));
pnt.setStyle(Paint.Style.STROKE);

RectF rect = new RectF();
rect.set(200, (200), 600, 600);
canvas.drawArc(rect, 270, i, false, pnt);

pnt.setColor(Color.parseColor("#2F9D27"));
rect = new RectF();
rect.set(200, (700), 600, 1100);
canvas.drawArc(rect, (270-i), i, false, pnt);
}
}


끝!!!

저작자 표시 비영리 변경 금지
신고
이 댓글을 비밀 댓글로