【Android】Ripple Effect 実装について

## はじめに
Androidでタッチフィードバックと言ったらRippleですね　:ok_hand:
発表されてから時間も立っていますが、Lolipop 〜 Oreoまで（Pieでも多分OK）で動くように対応したのでまとめます。CardViewを使った実装、色の指定について記載します。

## Ripple
http://material-design.storage.googleapis.com/publish/material_v_8/material_ext_publish/0B14F_FSUCc01RFdjQWE4ZXBseWM/Aware_02_MoveAway-v2.mp4

- クリックした後に灰色の波紋のように広がるタッチフィードバックがRippleです

## サンプルコード
https://github.com/yiwaisako/ripple_demo

- これから紹介するデザインを実装したコードです。この記事に記載していない詳細についてはこちらから確認できます。

## 動作環境
- compileSdkVersion 25
- minSdkVersion 19
- targetSdkVersion 25
- supportLibraryVersion 25.4.0

## 対象OS
-  Lolipop 〜 Oreo（Pieもおそらく大丈夫）


## 実装について

### デザイン
<img width="468" alt="スクリーンショット 2018-11-21 20.36.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/36517/f64b576a-a15f-1030-9c8c-b81e2c23424d.png">

- ①： 画像。クリックすると全体にRippleを表示する
- ②： タイトルと説明文。クリック時の動きは①と同じ
- ③、④： Readボタン、Trialボタン。クリックするとボタン内にRippleを表示する

### RippleDrawableの生成

``` ripple.xml
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="@color/red">
    <item
        android:id="@android:id/mask" 
        android:drawable="@android:color/white"/>
</ripple>
```
- 上記のように、XMLでRippleDrawable作成します。
- ```item```は画面をタッチした指を離したタイミングでRippleを表示するために指定します



### レイアウトXML（記述を省略するためクラスのみ記載）

```layout.xml
<android.support.v7.widget.CardView
    android:clickable="true"
    android:foreground="@drawable/ripple"
    >
    <RelativeLayout>
        <ImageView/>
        <RelativeLayout>
           <RelativeLayout>
                <TextView/>
                <TextView/>
           </RelativeLayout>
            <LinearLayout>
                <android.support.v7.widget.CardView
                    android:clickable="true"
                    android:foreground="@drawable/foreground_ripple">
                    <TextView
                        android:id="@+id/read_button_text"/>
               </android.support.v7.widget.CardView>
               <android.support.v7.widget.CardView
                    android:clickable="true"
                    android:foreground="@drawable/foreground_ripple">
                   <TextView/>
               </android.support.v7.widget.CardView>
            </LinearLayout>
        </RelativeLayout>
    </RelativeLayout>
</android.support.v7.widget.CardView>
```
- CardViewに``` android:clickable="true"　　android:foreground="@drawable/foreground_ripple"``` を指定するとRippleが表示されます。赤いタッチフィードバックが表示されるはずです。

### Rippleに色を指定

- 赤以外の色を指定します。

```MainActivity.kt

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {　//①
    val rippleColors = intArrayOf(R.color.colorAccent, R.color.colorPrimary, R.color.colorPrimaryDark,
            R.color.medium_turquoise, R.color.eclipse, R.color.malibu
    )

    val i = Random().nextInt(rippleColors.size)
    val mask = ContextCompat.getDrawable(context, R.drawable.mask)
    val color = ContextCompat.getColor(context, rippleColors[i])
    holder.root.foreground = RippleDrawable(ColorStateList.valueOf(color), null, mask).mutate()
}
```
- ①: Lolipop以上のときに、RippleDrawableの色をランダムに指定しています。


## 終わりに
- 改めてRippleについて記載しました、Lolipop以降でRippleを表示するには、CardViewやFrameLayoutを利用してレイアウトを考える必要がありそうです。参考になりましたら嬉しいです。

## 追記
- Pixel3（Pie)では、何も設定しないでもcolorPrimaryのRippleが表示されるようでした。機会がありましたら確認してみてください。