본문 바로가기
공부/안드로이드

Custom View

by 단순한 프로그래머 2025. 9. 21.

안드로이드에서 임의로 뭔가를 그리고 싶을 때

View를 상속받아 임의의 View를 생성하고 onDraw를 통해

원하는 것을 직접 그릴 수 있다.

아래 샘플은 화면상에 원점과 텍스트의 원점을 표시하고

텍스트를 그렸을 때 텍스트가 차지하는 영역을 구하여 사각형을 표시하였다.

 

결과이미지

 


 

CustomView 

커스텀뷰는 View를 상속받고 onDraw부분만 오버라이드하면

커스텀뷰가 위치하는 곳에 원하는 것을 화면에 그릴 수 있다

문자열의 너비와 높이를 구해 사각형을 그리기 위해서는 

paint - fontMetrics - descent와 ascent를 알고 있어야 한다.

구분 내용
Ascent 글꼴의 베이스라인에서 가장 높은 지점까지의 거리
Descent 글꼴의 베이스라인에서 가장 낮은 지점까지의 거리

 

class CustomView(context: Context, attrs: AttributeSet) : View(context, attrs) {

    val _paint = Paint()

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        canvas?.let {
            customDraw(canvas)
        }
    }

    fun customDraw(canvas:Canvas){
        _paint.style = Paint.Style.FILL
        _paint.color = Color.RED
        canvas.drawCircle(0f, 0f, 10f, _paint) //  원점

        val fTextX = 50f
        val fTextY = 200f
        val strText = "가나다라ABCabc123!@#"
        canvas.drawCircle(fTextX, fTextY, 10f, _paint) //  텍스트의 원점

        _paint.color = Color.GRAY
        _paint.textSize = 50f
        canvas.drawText(strText, fTextX, fTextY, _paint) // 텍스트 그리기

        val fTextW = _paint.measureText(strText)
        val fTextH = _paint.fontMetrics.descent - _paint.fontMetrics.ascent

        _paint.style = Paint.Style.STROKE
        _paint.strokeWidth = 1f
        _paint.color = Color.BLUE

        val rect = RectF(
        	fTextX,
            fTextY + _paint.fontMetrics.ascent, 
            fTextX + fTextW, 
            fTextY + _paint.fontMetrics.descent)
        canvas.drawRect(rect, _paint) // 텍스트 테두리 그리기
    }
}

 


 

ActivityMain 레이아웃

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".ActivityMain">

    <CustomView
        android:id="@+id/customView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </CustomView>
</androidx.constraintlayout.widget.ConstraintLayout>