본문 바로가기
안드로이드

안드로이드 View 좌우 동적으로 반원으로 만들기(GradientDrawable 활용 동적 방법)

by Best Coding 2025. 5. 5.
반응형

안드로이드 뷰 좌우 동적으로 반원 만들기(Gradient Drawable 활용)

 

 

 

 

안드로이드에서 View의 좌우를 반원처럼 만들기 위해 drawable XML에서 고정된 반지름 값을 사용하는 방법은 간단하지만, 화면 크기나 시스템 화면 배율(screen zoom)에 따라 정확한 반원이 되지 않는 한계가 있습니다. 이 글에서는 View의 실제 높이에 맞춰 반지름을 동적으로 설정하는 방법을 소개합니다.

 

 

이전 포스팅에 작성한 정적으로 View 좌우를 반원으로 만드는 방법은 아래 링크에서 확인할 수 있습니다.

2025.05.05 - [안드로이드] - 안드로이드 View 좌우를 반원으로 만드는 방법 (XML drawable 사용)

 

안드로이드 View 좌우를 반원으로 만드는 방법 (XML drawable 사용)

안드로이드에서 View의 좌우 끝을 반원 형태로 만드는 가장 간단한 방법은 drawable XML 파일을 이용하는 것입니다. 이 글에서는 shape drawable을 정의하고 이를 View의 배경으로 적용하여 반원 모양을

best-coding.tistory.com

 

 

 

 

1. 배경 drawable의 종류 이해하기

안드로이드에서는 XML로 정의한 drawable이 실제로 어떤 클래스의 인스턴스로 생성되는지 이해하는 것이 중요합니다. 일반적으로 다음 두 가지 경우가 많습니다:

반응형

 

1-1. shape drawable → GradientDrawable

XML에서 <shape> 태그로 정의한 drawable은 런타임 시 GradientDrawable 클래스로 변환됩니다. 예를 들어 다음 XML은:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#FF0000" />
    <corners android:radius="0dp" />
</shape>

 

코드에서는 다음과 같이 접근할 수 있습니다:

val background = view.background
if (background is GradientDrawable) {
    // radius 설정 가능
}

 

 

 

1-2. layer-list drawable → LayerDrawable

여러 개의 drawable을 겹쳐서 사용하는 <layer-list>는 LayerDrawable로 변환됩니다. 내부 아이템은 각기 다른 Drawable 객체가 될 수 있습니다. 또한 이 drawable은 런타임 시 GradientDrawable 클래스로 변환됩니다. 예를 들어 다음 XML은:

 

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/background_layer">
        <shape android:shape="rectangle">
            <solid android:color="#FF0000" />
            <corners android:radius="0dp" />
        </shape>
    </item>
</layer-list>

 

코드에서는 다음과 같이 접근합니다:

val background = view.background
if (background is LayerDrawable) {
    val shape = background.findDrawableByLayerId(R.id.background_layer)
    if (shape is GradientDrawable) {
        // radius 설정 가능
    }
}

 

참고: android:id를 XML에 반드시 지정해야 findDrawableByLayerId()로 접근할 수 있습니다.


 

 

2. GradientDrawable에 반지름 동적으로 설정하기

 

View의 높이를 기준으로 반지름을 계산하고 radius를 설정하면 반원 형태를 정확히 구현할 수 있습니다.

 

방법 1: cornerRadii 배열 사용

val radius = view.height / 2f
val background = view.background
if (background is GradientDrawable) {
    background.cornerRadii = floatArrayOf(
        radius, radius, // top-left
        radius, radius, // top-right
        radius, radius, // bottom-right
        radius, radius  // bottom-left
    )
    view.invalidate()
}

 

방법 2: setCornerRadius() 사용 (전체 모서리에 동일하게 적용)

val radius = view.height / 2f
val background = view.background
if (background is GradientDrawable) {
    background.cornerRadius = radius
    view.invalidate()
}

cornerRadius는 모든 모서리에 동일한 반지름을 설정할 때 사용합니다. 좌우만 반원으로 만들고 싶다면 cornerRadii를 사용하는 것이 더 정확합니다.

 

 

3. LayerDrawable 내부의 GradientDrawable 설정하기

 

LayerDrawable의 내부 drawable이 GradientDrawable일 경우에도 위와 동일한 방식으로 반지름을 설정할 수 있습니다.

val radius = view.height / 2f
val background = view.background
if (background is LayerDrawable) {
    val shape = background.findDrawableByLayerId(R.id.background_layer)
    if (shape is GradientDrawable) {
        shape.cornerRadii = floatArrayOf(
            radius, radius,
            radius, radius,
            radius, radius,
            radius, radius
        )
        view.invalidate()
    }
}

 

 

drawable XML만으로 구현하는 방법은 간단하지만, 화면 배율이나 뷰 크기 변화에 따라 비율이 깨질 수 있습니다. 정확한 반원 형태를 유지하려면 View의 실제 높이에 따라 반지름을 계산하고 GradientDrawable 또는 LayerDrawable에 동적으로 설정하는 방식이 가장 안전하고 일관성 있는 방법입니다.


반응형

댓글