あたも技術ブログ

セットジャパンコーポレーションの社員が運営しています。

【Android】Ripple Effectをコードで適応【Material Design】

今回はちょっとした小ネタになります。

Androidでボタンなどを押したときに出てくる波紋状のエフェクトですが、通常なら以下のようにxmlで記述し、backgroundに設定してあげることで実現することができます。

/values/colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="btn_color">#ffffaab3</color>
    <color name="btn_highlight_color">#ff4081</color>
</resources>


/drawable/btn_ripple.xml

<?xml version="1.0" encoding="utf-8"?>
    <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/btn_highlight_color">
    <item android:drawable="@color/btn_color" />
</ripple>

/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:background="@drawable/btn_ripple"
        android:text="Hello World!" />
</RelativeLayout>

今回はxmlを使用せずにコードでRipple Effectを実現する方法を書いていきます。
コード自体は簡単で、以下のようにコードを書いてeffectを適用させたいViewを渡してあげるだけです。

RippleEffect.java

public class RippleEffect {
    private static ColorStateList getPressedColorSelector(int normalColor, int pressedColor) {
        return new ColorStateList(new int[][] {
                new int[]{android.R.attr.state_pressed},
                new int[]{android.R.attr.state_focused},
                new int[]{android.R.attr.state_activated},
                new int[]{}
        }, new int[] {
                pressedColor,
                pressedColor,
                pressedColor,
                normalColor
        });
    }

    public static void setRippleDrawable(View v, int normalColor, int pressedColor) {
        RippleDrawable ripple =  new RippleDrawable(getPressedColorSelector(normalColor, pressedColor), new ColorDrawable(normalColor), null);
        ripple.setColor(ColorStateList.valueOf(pressedColor));
        v.setBackground(ripple);
    }
}



MainActivity.java

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn = (Button)findViewById(R.id.btn1);
        RippleEffect.setRippleDrawable(btn, getResources().getColor(R.color.btn_color), getResources().getColor(R.color.btn_highlight_color));
    }
}

基本的にはxmlで記述し、backgroundに設定してあげるやり方でいいと思いますが、動的に色を変えたい時などにはお勧めです。