2013/03/18
onListItemClick() の中で isChecked() を呼んではいけない?
どうも、Galaxy Nexus を 4.0.2 → 4.1.1 にアップデートしてからおかしくなったらしい。
調べてみると、ListActivity.onListItemClick() の中で CheckedTextView.isChecked() を呼んだ時の挙動が変化した模様。
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 のバージョンをチェックして乗り切ることは可能かもしれません。
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 件のコメント:
コメントを投稿