[Android]Ripple Effect (波紋)を表示する方法まとめ


はじめに

Ripple Effect とは UI コンポーネントを Click したときに発生する波紋のアニメーションのことです。
例えばですが Click する次のように Click した位置から波紋状に広がるアニメーションが表示されます。

この Ripple Effect ですが View によっては表示されません。
例えば次のように TextView では Click しても表示されません。

また表示されている View でも Background を変更してしまうと表示されなくなります。
例えば次のように Button の背景色を変えてしまった場合には表示されません。

というように Ripple Effect がうまく表示されないパターンは複数あります。
そのため困ることが多かったので Ripple Effect が表示されないときの対処方法をまとめようと思います。

本来であれば Ripple Effect の仕様が分かればよいのですが、
情報が少ないので対処方法だけをまとめようと思っています。 
なので Ripple Effect の詳細がわかる方はコメントしていただければ有り難いです。

Ripple Effect がでない View で Ripple Effect (波紋) を出す

TextView など Ripple Effect が表示できない View に対して
Ripple Effect を表示するには Clickable を true にして、 Background に ?attr/selectableItemBackground を設定する。

    <TextView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_margin="5dp"
        android:layout_gravity="center"
        android:foregroundGravity="center"
        android:clickable="true"
        android:background="?attr/selectableItemBackground"
        android:text="Hello World!"/>

次のように ?attr/selectableItemBackground を設定すると View を埋め尽くすように波紋が広がります。

その他に ?attr/selectableItemBackgroundBorderless を設定できます。

    <TextView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_margin="5dp"
        android:layout_gravity="center"
        android:foregroundGravity="center"
        android:clickable="true"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:text="Hello World!"/>

この場合は View を埋め尽くすように広がらず、 View サイズに応じた波紋だけが表示されます。

Background を指定した View に Ripple Effect (波紋)を出す

次のように Button の Background を設定してしまうと、
Ripple Effect が表示されなくなってしまいます。

    <Button
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:background="#aaffaa"
        android:text="Hello World!"/>

TextView では background に ?attr/selectableItemBackground を設定することで Ripple Effect を表示しました。
しかしすでに background に設定をしているのでこの方法は使えません。

なので background に背景を指定している場合は 次の Drawable ファイルを
background に貼り付けて Ripple Effect を表示するようにできます。

background.xml
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#bbffbb" />
        </shape>
    </item>
</ripple>
    <Button
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:padding="0dp"
        android:background="@drawable/background"
        android:text="Hello World!"/>

API Level 23 以上限定にはなりますが background を変更せずに
foreground 設定を変更することでも Ripple Effect を表示できます。

    <Button
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:padding="0dp"
        android:background="#bbffbb"
        android:foreground="?android:selectableItemBackground"
        android:text="Hello World!"/>

おわりに

おそらくですが Click できる View の background には 自動的に
?android/selectableItemBackground が貼り付けられるでしょうね…

なので Click できないものには最初から貼り付けられていないですし、
貼り付けられていても background を変更すると Ripple Effect が非表示になってしまうのでないかと

Ripple Effect は確認しづらい項目で、変化を見逃してしまいやすいですが、
おおよそこういうときに非表示になると把握しておき非表示となるのを防ぐしかなさそうです。

ライブラリもあるっぽい

RippleEffect というライブラリがあるみたいです。
これを使えば API Levle 9 以上で Ripple Effect を表示できるみたいです。