u-ryo's blog

CheckBox.checked drawable not shown

ListViewで、各行にcheckboxを表示させるような話があって。 暗い背景なので、defaultのdesignだと見にくいんですね。 なのでcustomの白っぽいのに差し替えようとしたんですが、 なかなかうまく行かなかったのです。 基本的には、res/drawable/に、

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:drawable="@drawable/ic_check_disabled"/>
    <item android:state_checked="true" android:state_pressed="false" android:drawable="@drawable/ic_check_on"/>
    <item android:state_checked="false" android:state_pressed="false" android:drawable="@drawable/ic_check_off"/>
    <item android:state_checked="true" android:state_pressed="true" android:drawable="@drawable/ic_check_on_pressed"/>
    <item android:state_checked="false" android:state_pressed="true" android:drawable="@drawable/ic_check_off_pressed" />
</selector>

と書いて(状態判定は上の行から順番になされる模様)、layoutで、

<CheckBox
  android:id="@+id/historySelected"
  style="@style/historyListCheckBox"
  android:button="@drawable/selector_checkbox"
/>

というように参照すればいいんです。 が、それだとcheckしても絵が変わらなかったんですね。 別途OnClickListenerに、

checkbox.setButtonDrawable(checkbox.isChecked() ? R.drawable.ic_check_on : R.drawable.ic_check_off);

が必要でした、というのはまだわかるんですが、 これを書いてもic_check_onの絵にならなかったんですね(ic_check_offの絵のまま)。 なんでだろ~、1日程悩みました。

結局、 stackoverflowのCan’t create custom arrayadapter with appcompat elements inside of itに書いてあったんですけど、 ListViewのAdapterを作る時のContextが、 getApplicationContext()で得られたものであったこと、 が敗因でした。getApplication()でもダメでした。 thisでないと、ic_check_onがdrawされませんでした。

adapter = new SimpleAdapter(this, someList, R.layout.some_listview, new String[]{...}, new int[]{R.id.someId,...});

thisで引き回すと、使ってるfieldとか色々引きずるから なるべくgetApplicationContext()にしましょうね、 というのを聞いたことがあるのですが、 なるほどと思ってそうすると、 結構色んな箇所で出るべきものが出なくなるんですよね。 気を付けないとなりません。