LoginSignup
14
16

More than 5 years have passed since last update.

Androidアプリでボタンの背景を動的に変える

Posted at

やりたいこと

こんな感じで、背景色を指定した角丸ボタンについて、プログラムから動的に色を変えたい。

スクリーンショット 2018-06-17 9.49.00.png

レイアウトファイルでのイメージ

xmlで固定の色でやる場合はこんなイメージ

ボタン背景用のDrawable。
ボタンが押された時と通常時で、別の色を指定したselectorを用意した。

res/drawable/button_back.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <corners android:radius="@dimen/button_radius" />
            <solid android:color="@android:color/holo_red_dark" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <corners android:radius="@dimen/button_radius" />
            <solid android:color="@android:color/holo_red_light" />
        </shape>
    </item>
</selector>

ボタンのレイアウト。上記ファイル(button_back.xml)をbackgroundとして指定している。

res/layout/sample_button.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/button_back"
    android:layout_width="150dp"
    android:layout_height="50dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:text="サンプル"
    android:textAllCaps="false"
    android:textColor="@color/button_text_color"
    android:textSize="@dimen/answer_button_font_size"
    android:textStyle="bold" />

コード上でやる場合

レイアウトファイルの
<selector>StateListDrawable
<shape>GradientDrawable
にそれぞれ置き換えられるらしい。

dynamic_background_button.kt
val button = View.inflate(context, R.layout.sample_button, null)
val radius = context.resources.getDimensionPixelSize(R.dimen.button_radius).toFloat()
val res = StateListDrawable()

val pressedColor = context.resources.getColor(android.R.color.holo_red_dark)
val pressedDrawable = GradientDrawable()
pressedDrawable.cornerRadius = radius
pressedDrawable.setColor(pressedColor)
res.addState(intArrayOf(android.R.attr.state_pressed), pressedDrawable)

val color = context.resources.getColor(android.R.color.holo_red_light)
val drawable = GradientDrawable()
drawable.cornerRadius = radius
drawable.setColor(color)
res.addState(intArrayOf(), drawable)

button.setBackgroundDrawable(res)

ちなみに角丸が不要で、背景色だけ変わればいいという場合はColorDrawableを使うと簡単そう。

dynamic_color_button.kt
val button = View.inflate(context, R.layout.sample_button, null)
val res = StateListDrawable()

val pressedColor = context.resources.getColor(android.R.color.holo_red_dark)
res.addState(intArrayOf(android.R.attr.state_pressed), ColorDrawable(pressedColor))

val color = context.resources.getColor(android.R.color.holo_red_light)
res.addState(intArrayOf(), ColorDrawable(color))

button.setBackgroundDrawable(res)

参考

Android create selector programmatically - Stack Overflow
https://stackoverflow.com/a/33986111

Shape drawableをxmlではなくJavaコードで動的に生成する - Qiita
https://qiita.com/guchio/items/bebc13db0d2c0ae03363

14
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
16