느려요

진짜로

IT/Mobile

[Android/JAVA] View에 그림자 속성(elevation)이 적용되지 않을 때 확인해야 할 3가지

느이 2023. 7. 5. 09:50

특정 뷰에 그림자 효과를 넣고 싶으면 해당 뷰의 elevation 값을 설정해주면 된다.

RecyclerView에 그림자를 적용한 모습

 

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="4dp"
    android:layout_marginRight="4dp"
    android:layout_marginBottom="4dp"
    android:background="@color/color_main_white"
    android:elevation="4dp"
    android:padding="4dp" />

elevation 값을 줬는데도 안되면 아래의 경우를 살펴보자

 

1. 여백 설정

뷰에 그림자를 설정하려면 그림자가 있을 여유공간이 있어야 하며, 공간이 없으면 그림자가 안나온다...

그래서 그림자를 설정하고 싶은 뷰의 layout_margin 값을 그림자 수치만큼 주거나

설정하고자 하는 뷰의 부모 뷰에 padding 값과 clipToPadding 값을 설정하여 여유공간을 만들어주면 된다.

 

2. background 설정

그림자도 설정했고 여유공간도 있는데 그림자가 안나오네?

background 값에 색상이나 모형을 설정해보자.

단, 투명한 색을 넣으면 그림자가 안생기므로, 불투명한 색상을 사용하면 생긴다!

왜 배경값을 넣어야 하는지 찾아봤는데, 개발자 문서에 아래와 같이 적혀있었다.

뷰의 배경 드로어블 경계는 그림자의 기본 모양을 결정합니다. 윤곽선은 그래픽 개체의 바깥쪽 모양을 나타내고 터치 피드백의 물결 영역을 정의합니다.

 

즉, 배경이 있어야 그 배경의 모형을 기준으로 그림자 윤곽선을 결정하고 그림자를 표현할 수 있다는 뜻이다.

그래서 배경이 없으니 윤곽선을 못정해서 그림자가 안나오는거군!

 

3. translationZ 값 확인

일반적으로 xml 화면에서 보이는 뷰는 2차원처럼 보이지만 실제로는 3차원으로 구성되어 있다.

따라서 각 뷰는 width, height 뿐만 아니라 depth도 가지고 있다고 생각하면 되는데, 이 depth는 편의상 Z축이라고 하겠다.

 

그럼 Z축의 값은 어떻게 생겨먹었는가?

Z축의 값은 그림자를 설정하기 위한 elevation 값과 개발자가 임의로 설정할 수 있는 translationZ 값으로 이루어져 있다.

Z값 = elevation + translationZ

 

그럼 Z속성으로 그림자는 어떻게 표시하는걸까?

안드로이드 개발자 문서에 보면 다음과 같이 설명되어 있다.

 

Z 속성으로 표현되는 뷰의 엘리베이션은 그림자의 시각적인 모양을 결정합니다. 예를 들어, 더 높은 Z값을 가진 뷰는 더 크고 부드러운 그림자를 표시합니다. 높은 Z값을 가진 뷰는 낮은 Z값을 가진 뷰를 가립니다. 하지만 뷰의 Z값이 뷰의 크기에 영향을 주지는 않습니다.

그림자가 생성되는 형태. Z축에 기반하여 생성되는 것을 알 수 있다.

즉, 그림자는 뷰의 z축에 영향을 받으며

z축의 값이 높을수록 크고 연하게, 값이 낮을수록 작고 진하게 표현될 수 있다는 뜻이다.

 

그런데 공교롭게도 Z축의 값이 부모 뷰의 Z축의 값과 같아버리면 그림자가 안보인다 ㅜㅜ

Z축 상에서 두 개의 뷰가 같은 높이가 되어버려 그림자를 덮어버리기 때문..

 

따라서 여유공간과 배경 색상까지 설정했는데도 그림자가 안보이면

뷰를 3차원적으로 생각해서 Z축의 값을 변경해보자.

사실 이거때문에 삽질해서 쓰는 글임

 

출처 : https://developer.android.com/training/material/shadows-clipping?hl=ko

반응형