SQLite를 사용하기 때문에 별 생각없이 CursorAdapter로 Listview를 구성하면 DB를 수정, 삭제하거나 Listview의 정렬방식 변경, 검색등과 같이 Listview상의 순서를 기존과 다르게 변경하는 경우 Item position 값이 꼬이는 문제가 생깁니다. 그래서 일반적으로 ArrayAdapter를 사용하는 경우처럼 Listview상의 Item을 터치하여 해당 Item값을 불러오는 Activity를 띄우려고 할 때 setOnItemClickListener에서 제공하는 position값을 그대로 사용하면 엉뚱한 결과값이 출력되거나 아에 죽어버리는 상황을 맞이하게 됩니다.




간단히 DB 삭제의 경우를 예로 들어보겠습니다.

위와 같이, setOnItemClickListener에서 제공하는 position값으로 DB를 삭제해버리는 경우, 겉으로 보기에는 제대로 지워진 것처럼 보이지만 실제로는 ListView의 position값과 DB값은 꼬여버립니다. 만약 position=1에 해당하는 item을 삭제한 후에 position=2에 해당하는 아이템을 터치하면 D에 해당하는 DB값이 출력되는 게 아니라 C에 해당하는 DB값이 출력될겁니다. 물론 position=1에 해당하는 아이템을 다시 터치하게 된다면 index=1이었던 DB값은 삭제된 후이기 때문에 예외처리를 안했다면 죽는 문제가 생기겠죠.


따라서, Listview의 position값을 그대로 사용하는 게 아니라 position에 해당하는 DB의 _id값을 불러와서 제어하는 것이 좋습니다.


listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
   @Override
   public void onItemClick(AdapterView adapterView, View view, int position, long l) {
      Intent intent = new Intent(MainActivity.this, InfoActivity.class);

      Cursor cursor = (Cursor) cursorAdapter.getItem(position);
      String index = cursor.getString(cursor.getColumnIndex("_id));
      int id = Integer.parseInt(index);

      intent.putExtra("id", id);
      startActivityForResult(intent, 0);
   }
});


먼저 getItem으로 현재 position에 있는 item값을 불러오고, 그 중 getColumnIndex로 _id값을 불러와서 그 id값을 기준으로 불러오시면 정상적으로 원하시는 DB값이 호출되는 것을 보실 수 있습니다.




참고


http://arabiannight.tistory.com/entry/368

+ Recent posts