본문 바로가기
코딩일기/android studio

안드로이드 독학 12일차 : 터치로 그림그리기

by 욱파이어니어 2021. 3. 25.
728x90
반응형

터치 예제 중의 가장 클래식한 예제인 터치로 그림 그리기를 해볼 예정이다.

 

내가 해볼것은 

1. 터치를 하면 그림 그릴 수 있게 하기

2. 지우기 버튼을 클릭하면 그림 그렸던 게 모두 지워지게 하기

 

이렇게 두가지이다. 일단은 xml부터 보자

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <wook.co.kr.TouchDraw
        android:id="@+id/draw"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <Button
        android:id="@+id/clear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="지우기"
        android:layout_gravity="center"/>
    
</LinearLayout>

여기서 넣은건 내가 만든 커스텀 뷰와 버튼 하나이다. 각각 뷰마다 id를 집어넣어줘서 MainActivity에서 컨트롤할 수 있게 했다. 그리고 weight를 넣어서 커스텀 뷰가 더 크게 하였다.

실행시켜보면 화면은 이렇다.

 

그럼 이제 MainActivity 소스를 보자.

 

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button b1 = (Button) findViewById(R.id.clear);
        final TouchDraw td = (TouchDraw) findViewById(R.id.draw);

        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                td.reset();
                Toast.makeText(getApplicationContext(), "지워졌습니다.", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

여기서 하는것은 xml에 있는 커스텀 뷰와 버튼을 id로 가져와서 각각의 객체에 집어넣었다.

그래서 b1이 클릭 되게 되면 커스텀 뷰에 있는 reset()을 호출하게 했다.

reset() 함수는 기존의 그림들을 지우는 부분이다.

 

그럼 이제 커스텀 뷰의 소스를 한번 보자

 

public class TouchDraw extends View {
    private float x, y; //좌표점을 받기위한 변수 선언

    private Paint paint = new Paint(); //onDraw()에서 그림 그리기 위해서 필요한 Paint 객체 생성
    private Path path = new Path(); //터치된 좌표를 저장하기 위한 Path 객체 생성

    public TouchDraw(Context context) {
        super(context);

        paint.setAntiAlias(true);//선을 매끄럽게 하기 위해서
        paint.setStrokeWidth(10f);//선의 두께를 10으로 설정
        paint.setColor(Color.BLUE);//선의 색깔을 파란색으로
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
    }

    public TouchDraw(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        paint.setAntiAlias(true);//선을 매끄럽게 하기 위해서
        paint.setStrokeWidth(10f);//선의 두께를 10으로 설정
        paint.setColor(Color.BLUE);//선의 색깔을 파란색으로
        paint.setStyle(Paint.Style.STROKE); //안의 내용을 채우지 않고 외곽선만 그림
        paint.setStrokeJoin(Paint.Join.ROUND); //
    }


    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawPath(path, paint);
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        x = event.getX();
        y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //터치됐을때 터치된 좌표를 저장해야함
                path.moveTo(x, y);//moveTo(x,y) -> 다음 윤곽점 시작점을 x, y로 설정한다.
                return true; //다른 이벤트 감지하기 위해서
            case MotionEvent.ACTION_MOVE:
                path.lineTo(x, y);//마지막으로 지정된 점에서 x,y 지점까지 선을 추가하는것
                break;
            case MotionEvent.ACTION_UP:
                break;
            default:
                return false;
            //해당 이벤트가 끝나지 않았음으로 인지하게 해서 다른 이벤트 감지 못하게 하려고
        }
        invalidate();
        return true;
    }
    public void reset(){
        path.reset(); //path에 저장된 모든 경로 지워주는 부분
        invalidate(); //다시 onDraw() 시켜주는 부분
    }
}

일단 Path 클래스가 뭔지 궁금할 것이다.

 

Path 클래스는 그래픽에서 제공하는(기본적으로 제공하는) 터치 좌표들을 누적시킬 수 있게 해주는 클래스이다.

그래서 우리는 이제 터치 이벤트에 따라서 path의 메서드를 설정해 주었다. 

자세한 내용들은 주석으로 설명해 놨기 때문에 참고하면 될 것 같다.

 

나는 소스를 작성하면서 paint안의 메서드와 path안의 메서드가 뭔지 몰라 헤맸는데

해당 부분은 아래 사이트를 참고하면 될 것 같다.

 

Paint부분 : aroundck.tistory.com/291

 

[Android/안드로이드] Paint 관련 함수들.

안녕하세요 돼지왕 왕돼지입니다. 오늘은 Paint 관련 함수들에 대해 알아보겠습니다. - void setAntiAlias(boolean ) : 경계면을 부드럽게 처리해준다. - void setARGB(a, r, g, b) - void setColor(int color) -..

aroundck.tistory.com

Path 부분 : developer.android.com/reference/android/graphics/Path

 

Path  |  Android 개발자  |  Android Developers

 

developer.android.com

느낀 점 : 안드로이드는 참 정말 많은 메서드들이 존재하는것같다... 다알기는 힘들것 같구 그때그때 사용가능한 메소드들이 있는지 확인해봐야겠다.

반응형