본문 바로가기

프로그래밍 노트/안드로이드

[Android/Kotlin] clipToPadding으로 그림자 잘림 방지하기

# 개요


안녕하세요! 개발하는 대학생, 나무입니다.

 

구글에서 강력하게 권하고 있는 디자인 가이드라인! 바로 material design입니다.

이 material design은 사용자로 하여금 보다 직관적이고 더 깔끔한 사용자 환경을 만들어줌으로써 따로 독자적인 UI를 구성하지 않는 한 아주 효과적인 디자인 기준이 되어줍니다.

 

특히! 여기서 빠질 수 없는 요소가 바로 "그림자"인데요,

 

출처 : material.io

위 그림과 같이 배경이 있는 View에 입체감을 불어넣어줌으로써 더욱 깔끔하고 체계적인 디자인을 가능케합니다.

 

더욱이 이 그림자는 CardView의 cardElevation이나 View의 elevation을 조절해주면 생기기 때문에 별도의 추가 작업이 필요하지 않습니다.

 

app:cardElevation=""
elevation=""

 

이면 충분하죠.

 

그래서 위 코드를 이용해 LinearLayout안에 CardView를 추가한 간단한 xml을 생성해보았습니다.

 

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="40dp">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardBackgroundColor="#2CC79C"
        app:cardCornerRadius="10dp"
        app:cardElevation="20dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="20dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="안녕 세계!"
                android:textColor="#ffffff"
                android:textSize="15sp"/>

        </LinearLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

 

 

# 문제점


 

AVD : Google Pixel 3 (Api 29)

"????"

 

그림자가 생각하는 것과 달리 예쁘게 나오지 않았습니다.

마치 양 옆이 잘린듯이...

 

그렇다면 이번에는 최상단 LinearLayout에 padding값을 없애고 CardView에 margin값을 추가해 똑같은 여백이 생기도록 해봅시다.

 

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="40dp"
        app:cardBackgroundColor="#2CC79C"
        app:cardCornerRadius="10dp"
        app:cardElevation="20dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="20dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="안녕 세계!"
                android:textColor="#ffffff"
                android:textSize="15sp"/>

        </LinearLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

 

AVD : Google Pixel 3 (Api 29)

이번에는 생각한 대로 정상적으로 나왔습니다.

 

그렇다면 첫번째 경우에선 어떤 점이 문제였을까요?

바로 부모 레이아웃의 padding이 하위 뷰의 그림자, 즉 뷰의 바깥쪽 경계를 잘라버렸기 때문입니다.

 

"그러면 그림자를 위해선 무조건 View의 margin값을 이용해 여백을 만드는 수 밖에 없는 건가요?"

 

 

# 해결책


이럴때 사용할 수 있는 속성이 바로 clipToPadding입니다.

 

기본적으로 true로 설정되어있는 이 속성을 false로 바꿔줌으로써 padding이 뷰의 바깥쪽 경계가 잘라버리는 것을 방지할 수 있습니다.

 

그럼 이를 이용해 padding을 쓰면서도 그림자가 잘리지 않도록 해볼까요?

 

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="40dp"
    android:clipToPadding="false">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardBackgroundColor="#2CC79C"
        app:cardCornerRadius="10dp"
        app:cardElevation="20dp">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="20dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="안녕 세계!"
                android:textColor="#ffffff"
                android:textSize="15sp"/>

        </LinearLayout>

    </androidx.cardview.widget.CardView>

</LinearLayout>

 

위 코드와 같이 padding값을 적용한 상위 레이아웃에 android:clipToPadding="false"를 추가해줍니다.

 

그리고 빌드를 해보면...

 

AVD : Google Pixel 3 (Api 29)

드디어! 저희가 원하는 대로 그림자가 그려졌습니다.

이제 불편한 잘림 현상에서 벗어날 수 있겠군요..

 

 

# 마치며


참고로, 이 clipToPadding은 그림자뿐만 아니라 RecyclerView에서 스크롤 시 상하단에 생기는 여백에도 마찬가지로 적용할 수 있습니다.

(RecyclerView에도 활용할 수 있다는 건 저도 찾아보다가 이번에 처음 알았어요..)

 

 

지금까지 나무였습니다.

다음 포스팅에서 봐요!

 

★댓글과 공감은 블로거에게 큰 힘을 줍니다★