터치 예제 중의 가장 클래식한 예제인 터치로 그림 그리기를 해볼 예정이다.
내가 해볼것은
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
Path 부분 : developer.android.com/reference/android/graphics/Path
느낀 점 : 안드로이드는 참 정말 많은 메서드들이 존재하는것같다... 다알기는 힘들것 같구 그때그때 사용가능한 메소드들이 있는지 확인해봐야겠다.
'코딩일기 > android studio' 카테고리의 다른 글
안드로이드 독학 14일차 : 멀티 터치 이벤트(Multi Touch event) 자바소스 예제 (0) | 2021.03.29 |
---|---|
안드로이드 독학 13일차 : 멀티 터치 이벤트(Multi Touch Event) (0) | 2021.03.25 |
안드로이드 독학 11일차 : 터치 이벤트(Touch Event) (0) | 2021.03.24 |
Android 독학 10일차 : 커스텀 뷰(Custom View) 만들기 (0) | 2021.03.18 |
Android 독학 9일차 : View 생명주기(View를 그리는 과정) (0) | 2021.03.16 |