以下のようなコードを Android 2.2 以前の端末で実行すると IllegalStateException が発生します。
List<Map<String, String>> data = new ArrayList<Map<String, String>>();
for (int i = 0; i < 10; i++) {
Map<String, String> map = new HashMap<String, String>();
map.put("item", String.valueOf(i));
data.add(map);
}
SimpleAdapter adapter = new SimpleAdapter(
this,
data,
android.R.layout.simple_list_item_single_choice,
new String[] {"item"},
new int[] {android.R.id.text1});
mListView.setAdapter(adapter);
LogCat の出力は以下のような感じ
E/AndroidRuntime(2226): java.lang.IllegalStateException: android.widget.CheckedTextView should be bound to a Boolean, not a class java.lang.String
これ、やっかいなのは Android 2.3 以降では普通に実行できるのです。
なので、きちんと古い端末で動作確認しないと問題を発見できません。
この問題の原因は SimpleAdapter の実装にあります。
2.3 以降の SimpleAdapter は TextView を継承している View に対して暗黙的にテキスト (データに対しtoString()したもの) を割り当ててくれるのですが、古いものにはそのような機能はありません。
そのため、2.2 以前を対象にする場合は ViewBinder を明示的に定義してやる必要があります。
具体的には、以下のように setAdapter より手前で setViewBinder を呼んでやります。
adapter.setViewBinder(new ViewBinder() {
@Override
public boolean setViewValue(View view, Object data, String textRepresentation) {
CheckedTextView v = (CheckedTextView) view;
v.setText((CharSequence) data);
return true;
}
});
mListView.setAdapter(adapter);