selectorを使うと、Buttonの押してる状態や、disabledの状態のときのボタンの見た目の変更ができる。
disabledのときは別画像を表示するようにしたかったのだが、動作させるとクラッシュしてしまった。
どうやらこれを見ると、selectorにattributeの値を入れてるとクラッシュしてしまうバグが有るらしい。
cf: Android Selector Drawable doesnt work with attributes
しかしattributesをなんとしても使いたい!!
というのでなんとかしたメモです。
selectorで画像を変える際は通称drawableでセットしてあげないといけない。
ならば、selectorのファイル自体をテーマごとに用意して、それをattributesで指定してあげれば解決できた。
popとofficialの2つのテーマがあったとして、それぞれのdrawableのxmlを準備する。
<?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>
<?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を準備します。
<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を指定するだけ!
<ImageButton android:id="@+id/plus_button" android:background="?attr/btn_plus" />
これでテーマごとにボタンの画像を差し替えることができるようになります。
おまけとして、rippleを適用する場合のxmlはこんな感じで定義してます。
<?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>
<?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が使えなくて一瞬絶望しましたが、考えようによってはうまく使えたので諦めず考えて良かったです。
こんにちは。virapture…
View Comments
Your article helped me a lot, is there any more related content? Thanks! https://www.binance.com/bg/register?ref=B4EPR6J0
I don't think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.
Your point of view caught my eye and was very interesting. Thanks. I have a question for you.