그림판 프로젝트에 진행하기 앞서 View의 onDraw 메소드를 오버라이딩해 Custom View를 그림판처럼 사용할 수 있다.
일련의 과정은 아래 그림과 같다.
Step1
1) View의 onDraw 메소드를 오버라이딩해 CustomView를 생성
2) CustomView 터치에 따른 로직을 처리하기 위해 onTouchEvent 메소드 오버라이딩
Step2
1) 생성한 CustomView를 MainActivity에 등록
2) CustomView를 조작하기 위한 다양한 리스너 설정
실습
Step1 View를 상속받아 CustomView 생성
- 점 찍기 CustomView.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | public class CustomView extends View { // '붓'에 해당하는 paint 클래스 변수 선언 private Paint paint; private float x, y, r=5; public CustomView(Context context) { super(context); // paint 클래스 선언 및 초기값 설정 paint = new Paint(); paint.setColor(Color.CYAN); paint.setStrokeWidth(5f); } @Override protected void onDraw(Canvas canvas) { // 해당 위치 점(원) 그리기 canvas.drawCircle(x, y, r, paint); } @Override public boolean onTouchEvent(MotionEvent event) { // 터치한 위치 값 추출 x = event.getX(); y = event.getY(); // 화면을 강제로 그리기 위해 호출하는 메소드 invalidate(); return true; } } | cs |
- 점 연결 CustomView.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | public class CustomView extends View { // '붓'에 해당하는 paint 클래스 변수 선언 private Paint paint; private float x, y, r=5; // 위치 값들을 저장하기 위한 List 생성 private List<Pos> data; public CustomView(Context context) { super(context); // paint 클래스 선언 및 초기값 설정 paint = new Paint(); paint.setColor(Color.CYAN); paint.setStrokeWidth(5f); } @Override protected void onDraw(Canvas canvas) { // 저장된 포인트 그리기 for (Pos p : data) { canvas.drawCircle(p.getX(), p.getY(), r, paint); } } @Override public boolean onTouchEvent(MotionEvent event) { // 터치한 위치 값 추출 x = event.getX(); y = event.getY(); // Pos 클래스를 생성해 데이터 저장 후 List에 추가 Pos pos = new Pos(x, y); data.add(pos); // 화면을 강제로 그리기 위해 호출하는 메소드 invalidate(); return true; } } /** * X, Y 좌표를 저장하기 위한 Pos 클래스 */ class Pos { float x, y; Pos(float x, float y) { this.x = x; this.y = y; } public float getX() { return x; } public float getY() { return y; } } | cs |
Step2 CustomView를 MainActivity에 등록
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class MainActivity extends AppCompatActivity { // ... // ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); stage = (FrameLayout) findViewById(R.id.stage); // Stage(FrameLayout)에 CustomView 추가 CustomView customView = new CustomView(this); stage.addView(customView); } // ... // ... } | cs |
문제점 및 해결
분명히 생각한대로 구현했다고 생각했는데 결과가 나오지 않았다.
(출처 - https://developer.android.com/reference/android/view/View.html#onDraw(android.graphics.Canvas))
찾아보니, View를 강제로 갱신하기 위해 invalidate 메소드를 호출한다고 한다. invalidate 메소드는 View의 onDraw 메소드를 호출해 화면을 갱신한다.
invalidate 메소드를 터치 메소드에서 호출하므로 문제 해결!
스크린 샷
점 찍기 |
점 연결 |
|
|
#안드로이드 그림판 만들기 #안드로이드 Paint #안드로이드 Path #Custom view #invalidate
댓글