[Android] View에 그림자 효과 주기
View에 그림자를 넣는 방법은 크게 두 가지가 있다. 하나는 xml에서 그림자 효과를 주려는 뷰에 elevation 속성을 사용하는 것이고 다른 하나는 직접 그림자 효과를 주는 xml을 작성하는 것이다. elevation을 사용하는 방법은 속성 하나만으로 그림자 효과를 낼 수 있어 별도의 구현이 필요없다는 장점이 있지만 그림자 방향이 아래로 고정되어 있으며 방향 변경이 불가능하다는 단점이 있다. 반면 xml로 작성하는 방법은 조금 번거롭더라도 원하는데로 그림자를 커스텀할 수 있다는 장점이 있다.
구현하려는 디자인에 따라 아래로만 그림자를 줘도 충분한 경우가 있는가 하면 그렇지 않은 경우도 있다. 그림자가 퍼지는 방향을 조절하거나 사방으로 퍼지게 하기, 내부 그림자 만들기 등 자유롭게 커스텀하고 싶은 경우 직접 레이아웃을 작성해야 한다. 이 포스팅에서는 그림자를 넣는 방법, 관련 속성, 몇 가지 예제를 다룰 것이다.
그림자를 적용할 때 주의해야 할 것은 이 리소스가 적용되는 View의 Parent View는 투명하지 않아야 한다는 것이다. 또한 그림자가 바깥을 향할 경우 View의 Parent View는 그림자의 색을 식별할 수 있을 정도로 밝아야 한다. 특히나 프로젝트에 적용한 테마의 배경색이 블랙 계열일 경우 그림자 적용 여부를 육안으로 확인할 수 없으므로 주의해야 한다. 나는 처음 그림자를 적용할 때 검은 배경 위에서 View의 그림자를 적용하려는 멍청한 짓을 해서 한참을 삽질한 경험이 있다.
그림자 그리기에 사용 가능한 속성
그림자를 직접 그릴 때 그림자 효과를 주는 옵션은 존재하지 않는다. 그림자는 그라데이션 효과를 통해 그려지는 것이고 그려질 방향과 크기까지 모두 직접 설정해야 한다.
- item : 레이어 역할을 하는 옵션이다. 이 옵션 안에 표시되는 것들은 하나의 레이어에 그려진다고 보면 된다. 먼저 선언한 속성이 가장 아래로, 나중에 선언한 속성이 가장 위에 표시된다.
- angle : 그라데이션이 그려질 각도를 지정한다. (90 = to top, 180 = to start, 270 = to bottom, 360 = to end)
- startColor : 그라데이션의 시작 색상을 지정한다.
- centerColor : 그라데이션의 중간 색상을 지정한다.
- endColor : 그라데이션의 끝 색상을 지정한다.
- centerX : 좌, 우에서 그라데이션을 어디까지 그릴지 결정한다. (0.1 ~ 1.0이 들어갈 수 있으며 0.1 = 10%라고 생각하면 된다.)
- centerY : 상, 하에서 그라데이션을 어디까지 그릴지 결정한다.
포토샵을 사용해본 사람이라면 item 속성을 레이어라고 이해하면 된다. 배경을 그리거나 특정 방향에서 뻗어 나오는 그림자를 그릴 때마다 item 속성이 하나씩 사용될 것이다.
그림자처럼 보일 그라데이션을 그리는데 사용할 속성은 startColor, centerColor, endColor다. 시작, 중간, 마지막 색상을 각각 검정, 회색, 배경색으로 지정하여 그라데이션을 그려준다.
그림자를 어느 방향으로 그릴지 결정하는 것은 angle이다. top, bottom, left, right 방향으로 그리는 것이 일반적이다.
그림자를 얼마나 그릴지를 결정하는 것은 centerY, centerX다. 이 값은 말로 설명하기 보다 0.01~0.99 까지 값을 바꿔 넣어가며 결과를 눈으로 확인하는 것이 빠를 것다.
만약 생성하려는 리소스가 둥근 모서리, 즉 rdius 옵션을 갖는다면 사용하는 모든 item 옵션에 dadius를 설정해야 한다.
Examples
내부 그림자 넣기
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="1dp"
android:left="1dp"
android:right="1dp"
android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
<corners android:radius="8dp"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<gradient
android:angle="180"
android:centerColor="#00FF0000"
android:centerX="0.9"
android:endColor="#5C000000"
android:startColor="#00FF0000" />
<corners android:radius="8dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<gradient
android:angle="360"
android:centerColor="#00FF0000"
android:centerX="0.9"
android:endColor="#5C000000"
android:startColor="#00FF0000" />
<corners android:radius="8dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<gradient
android:angle="270"
android:centerColor="#00FF0000"
android:centerY="0.1"
android:endColor="#00FF0000"
android:startColor="#6B000000" />
<corners android:radius="8dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:centerColor="#00FF0000"
android:centerY="0.1"
android:endColor="#00FF0000"
android:startColor="#6B000000" />
<corners android:radius="8dp" />
</shape>
</item>
</layer-list>
내부 그림자를 가지면서 모서리가 둥근 배경을 만드는 샘플이다. 배경이 될 첫 번째 item, 두 번째 item부터는 사방의 그림자를 그리는 역할을 하며 첫 번째 item을 제외한 나머지 item들을 모두 투명한 배경으로 설정하였다.
앞서 말했듯 그림자는 그라데이션을 그려서 그림자처럼 보이게 만드는 것이다. 처음은 검정색, 중간은 회색, 마지막은 흰색(배경색)으로 그라데이션을 그려 그림자가 그린 것을 볼 수 있다.