しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

RippleDrawableでボタン押下時のようなアニメーションを付ける

RippleDrawableを使ってTextViewなどを押した時にもボタンを押したときのようなアニメーションが出るようにします。

まずはXMLでRippleDrawableを定義します。
res/drawableフォルダの中にtest_drawable.xmlというファイルを作成して下のように記述します。
colorが選択時の色、android:drawableが背景色です。

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

作成したらTextViewに適用します。
下のようにTextViewのbackgroundに@drawable/test_drawableをセットします。

その際はandroid:clickable="true"も忘れずに付けます。
これがないとタップ時のアニメーションが表示されません。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FirstFragment">

    <TextView
        android:id="@+id/my_text"
        android:layout_width="60dp"
        android:layout_height="40dp"
        android:text="TEST"
        android:gravity="center"
        android:background="@drawable/test_drawable"
        android:textColor="@color/white"
        android:clickable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

起動すると下のように表示されます。
真ん中のTextViewをタップすればボタンのようなアニメーションになります。

ボタンのような選択色にしたい場合、colorを?android:colorControlHighlightにします。

<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item android:drawable="@android:color/darker_gray" />
</ripple>

下のようにshapeタグを使う事で角丸にしたりカラーコードでの色指定ができます。

<?xml version="1.0" encoding="utf-8"?>
<ripple
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:colorControlHighlight">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#ff0000" />
            <corners android:radius="8dp" />
        </shape>
    </item>
</ripple>

Kotlin上で背景色を利用したい場合、下のようにRippleDrawableを初期化してセットします。

val attrs = intArrayOf(android.R.attr.colorControlHighlight)
val typedArray = requireContext().obtainStyledAttributes(attrs)
val color = typedArray.getColor(0, 0)
val background = GradientDrawable().apply { this.color = ColorStateList.valueOf(Color.RED) }
binding.myText.background = RippleDrawable(ColorStateList.valueOf(color), background, null)
typedArray.recycle()

ここまでRippleDrawableの使い方を見てきましたが、RippleDrawableを使わなくてもforegroundに?attr/selectableItemBackgroundをセットする方法でもアニメーションさせる事は可能です。

<TextView
    android:id="@+id/my_text"
    android:layout_width="60dp"
    android:layout_height="40dp"
    android:text="TEST"
    android:gravity="center"
    android:foreground="?attr/selectableItemBackground"
    android:background="@android:color/darker_gray"
    android:textColor="@color/white"
    android:clickable="true"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />