Androidのselectorタグの書き方について
Androidでボタンのチェック状態等でリソースを切り替えるDrawable Resourceについてメモ。
selector
やitem
タグの記述の仕方について小一時間ハマった。
Drawable Resourceとは
公式ドキュメント。この中でも、今回は状態リスト(StateListDrawable)について。
StateListDrawable は XML 内に定義されるドローアブル オブジェクトで、オブジェクトの状態に応じて、同一のグラフィックに異なる画像を使用します。 たとえば、Button ウィジェットは複数の状態(押下状態、フォーカス状態、どちらでもない状態)をとりますが、状態リストのドローアブルを使用すると、状態に応じて異なる背景画像を使うことが可能です。
やりたいこと
今回ハマったのは、RadioGroupで囲ったRadioButtonのチェック状態の表示設定のため、 RadioButtonにStateListDrawableを設定した場合を例に書いていく。
仕様はこんな感じ。
- RadioGroupタグ内にRadioButtonを4つ配置
- 外枠(RadioGroup)
- 角丸4dp(
corners=4dp
) - 枠線色指定(
stroke.color
) - 枠線幅指定(
stroke.width=1dp
) - 塗りつぶし色指定(
solid
)
- 角丸4dp(
- 項目(RadioButton)
- 角丸4dp(
corners=4dp
) - チェック状態・未チェック状態・押下状態でそれぞれ塗りつぶし色を指定
- チェック状態・未チェック状態でそれぞれテキスト色を指定
- 未チェック状態は角丸を指定しない
- 角丸4dp(
仕上がりはこんな感じ。
単純に色を指定するだけなら、こちらのY.A.Mさんの記事のようにcolor
タグで指定すればOK。
y-anz-m.blogspot.com
backgroundに適用するDrawable
下記のようにbackground
にshape
と塗りつぶし色を指定する場合は、solid
で指定する。
<!-- drawable/toggle_background.xml --> <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" > <shape android:shape="rectangle"> <corners android:radius="@dimen/round_corners"/> <solid android:color="@color/colorAssort3"/> </shape> </item> <item android:state_selected="false"> <shape android:shape="rectangle"> <corners android:radius="@dimen/round_corners"/> <solid android:color="@color/colorBase2"/> </shape> </item> </selector>
<!-- 使用例 --> <RadioButton android:background="@drawable/toggle_background" />
下記のようにcolor
タグと併用しようとすると、先にあるタグ(この場合はcolor
タグ)のみ読み込まれて、角丸がきちんと表示されないため注意。
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_selected="true" > <color android:color="@color/colorAccent2" /> <!-- shape以下は適用されない --> <shape android:shape="rectangle"> <corners android:radius="@dimen/round_corners"/> </shape> </item> </selector>
また、上記の書き方だとxmlが長くなりがちなので、drawable
プロパティでDrawableResourceを指定する形の方が見やすくなる。
<!-- drawable/radio_checked.xml --> <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="@dimen/round_corners"/> <solid android:color="@color/colorAssort3"/> </shape> <!-- drawable/radio_pressed.xml --> <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="@dimen/round_corners"/> <solid android:color="@color/colorAccent3"/> </shape>
<!-- drawable/toggle_background.xml --> <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/radio_checked" android:state_selected="true" /> <item android:drawable="@drawable/radio_pressed" android:state_selected="false" /> </selector>
textColorに適用するDrawable
textColor
に状態リストを適用する場合も上記と同様。
ただし、background
と違い、こちらはitem
タグのcolor
プロパティで指定する必要がある。
<!-- drawable/toggle_textcolor.xml --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/colorBase2" android:state_checked="true"/> <item android:color="@android:color/darker_gray" android:state_checked="false"/> </selector>
まとめ
要はshape
にsolid
あるんだから、塗りつぶしはそっちを使おうねというだけ。