2013/03/18
onListItemClick() の中で isChecked() を呼んではいけない?

どうも、Galaxy Nexus を 4.0.2 → 4.1.1 にアップデートしてからおかしくなったらしい。
調べてみると、ListActivity.onListItemClick() の中で CheckedTextView.isChecked() を呼んだ時の挙動が変化した模様。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class MainActivity extends ListActivity { private static final String TAG = "MainActivity" ; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); String[] listItems = { "1" , "2" , "3" }; getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); ListAdapter adapter = new ArrayAdapter<String>( this , android.R.layout.simple_list_item_multiple_choice, listItems); setListAdapter(adapter); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { // ↓ 少なくとも Android 4.2 までは空関数 // super.onListItemClick(l, v, position, id); CheckedTextView cv = (CheckedTextView) v; Log.d(TAG, "isChecked " + cv.isChecked()); } } |
これを、Android 4.0.4 のエミュレータで動作させると以下の通り
// OFF → ON isChecked false // ON → OFF isChecked true |
Android 4.2 のエミュレータで動作させると以下の通り
// OFF → ON isChecked true // ON → OFF isChecked false |
完全に動作が逆転しています…
そもそも、以前は「チェックしたのに isChecked が false」という直感に反した仕様だったので、正しい動作をするようになったと言えるのかもしれません。
ただ、この変更がどのような意図で行われたのかが不明です。
Android Developersはチェックしたのですが、それらしい記述を見つけることはできませんでした。
バグフィックスなのか、たまたま挙動が変わってしまったのか…
もし、詳しい方がいらっしゃいましたら、コメントやTwitterで是非教えてください。
とりあえずは、以下のように Android のバージョンをチェックして乗り切ることは可能かもしれません。
1 2 3 4 | CheckedTextView cv = (CheckedTextView) v; boolean isChecked = (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) ? !cv.isChecked() : cv.isChecked(); |
ただし、仕様が明確に提示されていない以上、今後もまた変更が入る可能性はあります。
つまり、
onListItemClick()
の中では isChecked()
を呼ばない方が無難だという事になります。しかし、チェックされた瞬間に動作させたいことってありますよねぇ…
続き: OnItemClickListener.onItemClick() の中で isChecked() を呼んではいけない?
0 件のコメント:
コメントを投稿