[ Android ] 丸く広がるRippleを、サクッと実装


簡易的にタッチフィードバックのないボタンやレイアウト、タップ範囲が狭くなってしまったボタンなどに、範囲外に丸く広がるRippleでタップ感、領域を少し増やします。

こんな感じ(画質悪くてごめんなさい..)

Rippleを出したい要素の外側を、FrameLayout(パーツをひとつだけ配置して使用するレイアウト)で囲って、重ねてあげます。
この実装は、FrameLayoutを継承しているレイアウトでも使えます。

表示したいRippleの範囲は、paddingして操作できます。

<FrameLayout
    style="@style/RippleFrameStyle"
    android:padding="20dp">

    <Button
        style="@style/ButtonStyle"
        android:background="@drawable/icon" />

</FrameLayout>

適用するスタイルはこんな感じです。
切り分けてあげると使いまわせます。

style.xml
<!--リップルエフェクトを出すための親レイアウト-->
<style name="RippleFrameStyle">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:layout_centerVertical">true</item>
    <item name="android:background">?attr/selectableItemBackgroundBorderless</item>
    <item name="android:clickable">true</item>
    <item name="android:focusable">true</item>
</style>

<!--配置する見た目となるレイアウト-->
<style name="ButtonStyle">
    <item name="android:layout_width">30dp</item>
    <item name="android:layout_height">30dp</item>
    <item name="android:layout_centerVertical">true</item>
    <item name="android:clickable">false</item>
</style>

タッチフィードバックを親となるViewGroupに指定してあげるイメージです。

FrameLayout側でclickableとfocusableをtrueにして、クリック、フォーカスを可能にしてあげます。
さらに、内部のパーツがクリック可能であれば、clickableを取り除いてあげます。

そして、親となるFrameLayoutに、おなじみ?attr/selectableItemBackgroundBorderlessを設定してあげます。

ちなみに、selectableItemBackgroundBorderlessは、APIレベル21(Lollipop)以上限定です。

カスタム アニメーションの定義

ですので、何らかの動的な処理(onClickListenerやら)を設定する場合、FrameLayout自体を指定してあげて下さい。

UIにそんなに実装コスト割けないけど、取り急ぎMaterial Designぽいタップ感出したい!って言う方はこれだけやってあげると少し華やかになる、かも、しれないです。

もっと素敵な実装方法有りましたらご教授頂きたいです。