[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が使えなくて一瞬絶望しましたが、考えようによってはうまく使えたので諦めず考えて良かったです。




 
         
         
         
        