성장기록지

ShapeableImageView로 이미지 뷰 radius 적용 (w.내부 구현) 본문

개인 프로젝트

ShapeableImageView로 이미지 뷰 radius 적용 (w.내부 구현)

pengcon 2025. 1. 12. 16:40

적용 계기

다음과 같은 배너를 Custom View로 구현하고자 하였다. (현재는 배너 이미지로 대체하였다. 이유는 아래 서술)

모델 이미지의 오른쪽 아래를 보면 배너와 같이 라운딩 처리가 되어있는것을 확인하였다.

디자인의 요구사항과 똑같이 라운딩 처리를 해주고자 하였다.

적용 과정

먼저 이미지뷰에 라운딩 처리를 하는 법을 찾기 위해 구글을 검색하였다.

사진과 같이 나오는 래퍼런스들은 많지만, 다 만족스럽지 않았다.

clipToOutline을 통해 코드에서 동적으로 할당하거나,

CardView를 활용하거나 하여 여러모로 불편한 조건들이었다.

그러던 중, 부스트캠프 동료에게서 ShapeableImageView를 사용해보라는 말을 들었다!

 

ShapeableImageView

적용하는 법은 간단하다.

ImageView를 ShapeableImageView로 바꿔준 후,

app:shapeAppearanceOverlay 속성에 style에서 정의한 값을 넣어주면 된다.

<com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/iv_banner_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/banner_img"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:shapeAppearance="@style/AppRoundedImage" />
<style name="AppRoundedImage">
    <item name="cornerSize">32dp</item>
</style>

 

그렇다면 어떻게 ImageView와 다르게 style이 적용 가능한 것일까?

 찾아봤을 때 구글에 나와있지 않아 직접 알아보도록 하겠다!

 

ShapeableImageView의 내부 구현 알아보기

 

우선 ShapeableImageView의 코드를 들어가보았다.

ShapeableImageView는 AppCompatImageView를 상속받는다!

 

참고로 AppCompatImageView는 ImageView를 상속받는 친구다.

 

계층구조를 파악 후 ShapeableImageView 를 보던중,

다음과 같이 shapeAppearanceModel을 할당하는 코드를 볼 수 있었다.

 

그렇다면 shapeAppearanceModel 안에서는 어떻게 라운딩을 처리할까?

아래와 같이 setAllCorners를 통해  내가 float값으로 전달해준 32dp만큼 

Corner를 적용해주는 것이였다!

더 자세하게 알아보고 싶었지만, 코드설명이 주석이 없는것도 많기에

학습이 어려워서 이정도만 알아보도록 하였다.

 

적용 후기

이미지를 손쉽게 커스텀 할 수 있다는 점이 장점이였고,

매우 유용하다고 생각하였다!

하지만 배너를 ConstraintLayout을 통해 커스텀 뷰로 그리다 보니

요소들의 배치가 들쑥날쑥하게 되었고,

그냥 이미지로 추출하여 수정 적용하기로 결론지었다..

 

또한 커스텀뷰로 만들었을 때 얻는 이점이 크게 없기에,

커스텀 뷰를 마구잡이로 사용하지 말자는 교훈도 얻게 되었다.

(의미없는 레이아웃 중첩이 발생하기에)