やりたいこと
こんな感じで、背景色を指定した角丸ボタンについて、プログラムから動的に色を変えたい。
レイアウトファイルでのイメージ
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