[Android]selectorでもattributeを使いたい!
selectorを使うと、Buttonの押してる状態や、disabledの状態のときのボタンの見た目の変更ができる。
disabledのときは別画像を表示するようにしたかったのだが、動作させるとクラッシュしてしまった。
どうやらこれを見ると、selectorにattributeの値を入れてるとクラッシュしてしまうバグが有るらしい。
cf: Android Selector Drawable doesnt work with attributes
しかしattributesをなんとしても使いたい!!
というのでなんとかしたメモです。
対策
selectorで画像を変える際は通称drawableでセットしてあげないといけない。
ならば、selectorのファイル自体をテーマごとに用意して、それをattributesで指定してあげれば解決できた。
popとofficialの2つのテーマがあったとして、それぞれのdrawableのxmlを準備する。
1 2 3 4 5 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/official_btn_plus_2x" /> <item android:drawable="@drawable/official_btn_plus_disabled_2x" android:state_enabled="false" /> </selector> |
1 2 3 4 5 |
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/pop_btn_plus_2x" /> <item android:drawable="@drawable/pop_btn_plus_disabled_2x" android:state_enabled="false" /> </selector> |
いずれも通常の状態とdisable時のボタンの様子を表してます。
次に先程作成したdrawableをattributesで呼び出せるようにstyles.xmlを準備します。
1 2 3 4 5 6 7 8 9 10 |
<resources> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"></style> <style name="OfficialAppTheme" parent="AppTheme"> <item name="btn_plus">@drawable/official_btn_plus</item> </style> <style name="PopAppTheme" parent="AppTheme"> <item name="btn_plus">@drawable/pop_btn_plus</item> </style> <attr name="btn_plus" format="reference" /> </resources> |
ここまできたら準備完了!
あとはButtonで先程作ったattributeを指定するだけ!
1 2 3 4 |
<ImageButton android:id="@+id/plus_button" android:background="?attr/btn_plus" /> |
これでテーマごとにボタンの画像を差し替えることができるようになります。
Rippleの場合のselector
おまけとして、rippleを適用する場合のxmlはこんな感じで定義してます。
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/color_white"> <item> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/official_btn_plus_disabled_2x" android:state_enabled="false" /> <item android:drawable="@drawable/official_btn_plus_2x" /> </selector> </item> </ripple> |
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8"?> <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/color_white"> <item> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/pop_btn_plus_disabled_2x" android:state_enabled="false" /> <item android:drawable="@drawable/pop_btn_plus_2x" /> </selector> </item> </ripple> |
rippleの場合はrippleの中でselectorを定義するのがコツ。
まとめ
selectorでattributeが使えなくて一瞬絶望しましたが、考えようによってはうまく使えたので諦めず考えて良かったです。