GDSC HUFS 4기/Kotlin Team #7

[7팀] 드로잉 앱 안드로이드 12 part 2

jorippppong_조리퐁 2022. 11. 14. 16:05

 

이 글은 유데미 강의 Android 12 및 Kotlin 개발 완전 정복을 참고하여 작성하였습니다.

작성자 : 조유리

개발환경은 Windows, Android Studio입니다. 

 

 

1. 그림을 그릴 수 있는 기본 환경 설정

1) 그림을 그릴 캔버스 설정하기 : onDraw()

2) 사용자가 화면을 터치했을 때 어떤 일이 일어나는 지 설정 : onTouchEvent()

motion event에서 중요한 3가지

① ACTION_DOWN : 손가락을 댔을 때

② ACTION_MOVE : 손가락으로 드레그 했을 때

③ ACTION_UP : 손가락을 들었을 때

//DrawingView.kt    
		//뷰의 크기가 변경되었을 때 레이아웃 안에 설정되게 하는 메소드
    //바꿀 때마다 변경사항 바로 적용
    //override : 이 함수가 뷰 클래스 안에 있기 때문에 재정의 해서 사용 하는 것
    override fun onSizeChanged(w: Int, h: Int, wprev: Int, hprev: Int) {
        super.onSizeChanged(w, h, wprev, hprev)
        //bitmap 설정 : 폭, 넓이, 배열(각 픽셀이 각각 4바이트에 저장되고, 각 채널은 8비트의 정밀도로 저장) -> 다양한 색 사용 가능
        mCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        //위의 비트맵을 캔버스 비트맵으로 사용
        //null타입이라서 뒤에 !! 사용
        canvas = Canvas(mCanvasBitmap!!)
    }



    //그림을 그릴 캔버스 설정
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        //drawBitmap을 불러움. 이걸 전달해서 그림을 그리고 싶다고 알려서 우리가 만든 비트맵인 mCanvasPaint을 사용
        mCanvasBitmap?.let {
            canvas.drawBitmap(it, 0f,   0f, mCanvasPaint)  //left:0f, top:0f의 위치로 그림(왼쪽 상단, 좌표)
        }


        //화면에 선이 계속 보이게 하는 코드
        for (p in mPaths) {
            mDrawPaint?.strokeWidth = p.brushThickness  //strock -> 붓의 두께 설정
            mDrawPaint?.color = p.color  //색 설정
            canvas.drawPath(p, mDrawPaint!!)
        }

        if (!mDrawPath!!.isEmpty) {
            mDrawPaint?.strokeWidth = mDrawPath!!.brushThickness  //strock -> 붓의 두께 설정
            mDrawPaint?.color = mDrawPath!!.color  //색 설정
            canvas.drawPath(mDrawPath!!, mDrawPaint!!)
        }

    }

    //사용자가 화면을 터치했을 때 어떤 일이 일어나는지 설정
    override fun onTouchEvent(event: MotionEvent): Boolean {
        val touchX = event.x //x의 이벤트
        val touchY = event.y //y의 이벤트

        when (event.action) {
            //motion event에서 중요한 3가지
            //1번: 손가락을 댔을 때
            MotionEvent.ACTION_DOWN -> {
                mDrawPath?.color = color  //원하는 색
                mDrawPath?.brushThickness = mBrushSize  //원하는 두께

                mDrawPath?.reset() //가지고 있던 걸 리셋
                mDrawPath?.moveTo(
                    touchX,
                    touchY
                ) //(x,y)로 이동
            }
            //2번: 손가락으로 드레그 했을 때
            MotionEvent.ACTION_MOVE -> {
                mDrawPath?.lineTo(
                    touchX,
                    touchY
                ) //처음부터 마지막 드레그한 좌표까지 줄을 생성
            }
            //3번 : 손가락을 들었을 때
            MotionEvent.ACTION_UP -> {

                mPaths.add(mDrawPath!!) //그림그린걸 저장

                mDrawPath = CustomPath(color, mBrushSize)
            }
            else -> return false  //다른 일이 발생하지 않도록, 위의 3가지가 아니면 아무 일도 일어나지 않게 설정
        }
        //
        invalidate()
        return true
    }

 

2. 가장자리에 회색 테두리 만들기

//background_drawing_view_latout.xml
//android:background 에서 온 친구
//가장자리에 회색 테두리를 만들고, 그 안에서만 그릴수 있게 설정
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">  //직사각형 모양

    <solid android:color="#FFFFFF" />  //흰색

    <stroke
        android:width="0.5dp"
        android:color="#9AA2AF" />  //회색의 테두리를 만든다.
</shape>

3. 브러쉬 크기 설정하기

//DrawingView.kt
		//float 사용 이유: 화면의 값들이 float을 사용하기 때문
    //처음에 0으로 설정했는데, newSize로 덮어 쓴다.
    fun setSizeForBrush(newSize: Float) {
        mBrushSize = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, newSize,
            resources.displayMetrics  //측정기준
        //브러쉬의 크기가 newSize로 설정되지만, 화면의 크기에 비례하게 변경 된다.
        )
        mDrawPaint?.strokeWidth = mBrushSize  //실행중인 화면에 맞게 설정
    }
//MainActivity 
private var drawingView: DrawingView? = null

drawingView = findViewById(R.id.drawing_view)  //id로 찾는다. 
//우리가 만든 drawing view를 사용하기 위해서는 main에서 id로 찾은 후 사용해야 한다.
drawingView?.setSizeForBrush(20.toFloat())  //brush의 크기 설정