본문 바로가기

Android

[Android] Ripple Effect (눌렀을 때 변하는 Background)

클릭 효과

안드로이드 앱을 사용하다 보면 다음과 같은 터치 효과를 자주 볼 수 있습니다

Youtube앱
GooglePlay앱

눌린 곳부터 시작해 퍼지면서 색이 변합니다. 깔끔한 효과와 함께 눌렀다는 느낌을 줍니다.

이와 같은 효과를 Ripple Effect라 하며 Android에서 XML을 통해 사용하는 방법을 알려드리겠습니다(SDK 21 이상에서 가능).

1. 경계가 없는 리플(Unbounded Ripple)

View의 크기를 벗어나 Ripple 효과가 생깁니다. YouTube에서는 Background Color가 없는 ImageButton들에 사용됩니다.

drawable/ripple_unbounded.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- android:color = Ripple Effect의 색깔 좀 반투명으로 나온다 -->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="#A0A0A0" />
layout/activity_main.xml
...

<ImageView
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:background="@drawable/ripple_unbounded"
    android:clickable="true"
    android:focusable="true"
    android:src="@drawable/ic_play_arrow_white" />
<!-- Image는 재생버튼을 예시로 -->
<!-- clickable이 활성화 되어있어야 Ripple효과가 발동한다 -->

...

점선으로 표시된 부분이 View의 크기입니다. 크기를 벗어나 Ripple 효과가 적용된 모습입니다.

2. 배경이 있는 리플(Background Ripple)

XML을 통해 Background로 사용될 drawable, shape을 넣을 수 있습니다. Ripple 효과는 Background의 모습 안에서만 나타납니다.

drawable/ripple_background.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorHighlight">
    <!-- Background가 될 Item, 단순한 Rectangle Shape를 예시로 했다 -->
    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
        </shape>
    </item>
</ripple>
layout/acitivity_main.xml
...

<View
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:layout_margin="20dp"
    android:background="@drawable/ripple_background"
    android:clickable="true"
    android:focusable="true" />

...

drawable/ripple_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorHighlight">
    <!-- Background을 일반적인 Drawable로 설정 -->
    <item
        android:id="@android:id/background"
        android:drawable="@drawable/ic_android"></item>
</ripple>

3. 마스크가 있는 Ripple(Masked Ripple)

Ripple효과의 범위를 Background가 아닌 다른 것으로 설정할 수 있습니다.

drawable/ripple_mask.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/colorHighlight">
    <item android:id="@android:id/mask">
        <shape android:shape="oval">
        <!-- 마스크의 색상은 영향을 끼치지 않는다 -->
            <solid android:color="@android:color/darker_gray" />
        </shape>
    </item>
    <item android:id="@android:id/background">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />
        </shape>
    </item>
</ripple>

마스크로 설정한 원까지만 Ripple효과가 발생한 모습이다

예제에서는 Ripple Drawable들을 android:background에 넣었지만 ImageView의 src에 넣어도 정상 작동을 합니다.