마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

커스텀 리스트뷰 체크박스로 삭제.

0 추천
for(int k=0; k<listItem.size(); k++)
				{
					Log.e("저장된값은?",listItem.get(k)+"");
					int pos = listItem.get(k);
					studentArr.remove(pos);
				}
				listItem.clear();
				sAdapter.notifyDataSetChanged();

안녕하세요, 안드로이드 초보입니다.(__)

커스텀 리스트뷰를 체크박스/이름/전화번호 형식으로 만들고

동적으로 추가,삭제하는 것을 구현하려고 합니다. 

삭제 시, 체크 된 데이터들만 array에서 제거하려고 하는데 삭제가 잘 안됩니다..

위 코드는 삭제버튼을 눌렀을 때 처리하는 코드입니다.

integer형 arraylist에 제가 체크해놓은 포지션을 저장했다가, 삭제할 때 사용합니다.

log로 저장된 값을 출력할 때 제가 체크한 포지션으로 나옵니다.

(0,1,8 등으로)

현재는 배열에 9명의 학생이름을 담아서 출력하는데, [0~8인덱스]

인덱스에러가 발생합니다..마지막학생을 삭제하려고 하면 

java.lang.IndexOutOfBoundsException: Invalid index 8, size is 7 이 에러가 발생하는데요..

제가 위 코드에서 실수한 것이 있는지 조언 좀 부탁드립니다..

해당 에러를 검색해보니 사이즈 외의 것을 처리하면 발생하는 오류라는데요..

맨 위의 1,2번째 학생을 삭제하면 1,3번째 학생이 삭제됩니다...

먼가 로직을 잘못짠거같은데 ... 복잡해서 어떻게 해야할지 모르겠습니다.

 

망고사탕 (5,000 포인트) 님이 2015년 9월 23일 질문

4개의 답변

+1 추천
 
채택된 답변

포지션 0 1 2 3 4 5 6 7 8

이름  a b c d e f g h i

로 포지션이 있고, 1,2번을 체크하고 포문을 돌립시다. 그러면 1번째 돌때 

 

i=0

포지션 0 1 2 3 4 5 6 7 8

이름  b c d e f g h i

 

이렇게 되겠죠? 그러면 두번째 돌아봅시다

 

i=1

포지션 0 1 2 3 4 5 6 7 8

이름  b c d e f g h i

여기서 i=1이므로 c가 삭제됩니다.

 

그러므로, 삭제가 되는 경우 i--; 를 줌으로써, 1,3 삭제 문제는 해결 할 수 있구요,

IndexOutOfBoundsException 조건을 studentArr.size(); 로 주면 문제가 해결되지 않을까 싶습니다.

길버트공원 (1,720 포인트) 님이 2015년 9월 24일 답변
망고사탕님이 2015년 9월 24일 채택됨
+1 추천

어레이 삭제 하실때 많이들 하시는 실수죠~~!

로그를 보시면 아시겠지만 삭제가 한번 이루어지면 어레이의 포지션 값들이 전부 변함은 물론 크기 까지 달라지는데 제대로 삭제가 될리 만무 하겠죠?

결국 마지막에가서는 줄어든 크기의 인덱스를 참조 하게 되니 에러가 나구요...

어레이 삭제 작업을 하실때는 추가와는 반대로 어레이 뒤에서 부터 삭제 해주시면 됩니다!!!

즉 포문 조건을 

for(int k=listItem.size(); k>0 k--)

 

요로코롬 해주시면 되긋죠?

ThisPlus (46,920 포인트) 님이 2015년 9월 24일 답변
0 추천
답변 주신 분들 감사합니다.

뒤에서부터 삭제하는건 이해했습니다.. 조언해주신대로 수정했는데,

이게 또 문제가 발생하네요..

체크박스를 뒤죽박죽 체크..즉, 순서대로 체크하지 않고

1번체크-3번체크-2번체크 이런식으로 하면, index에러가 나거나 덜 삭제가 됩니다;

체크된 저장값 을 확인해보니 1,0,2 이렇게 체크한 순서대로 나오는데..

이걸 정렬해야 하나요?
망고사탕 (5,000 포인트) 님이 2015년 9월 24일 답변
그런 경우에는 인덱스로 하지말고, 학생 이름으로 체크하세요. 아니면 해시로 묶는것도 한방법
아 체크 리스트를 따로 관리 하시는군요~~!
그럼 당연히 정렬해야지요~!
리스트 하나에 체크 값을 넣어서 관리 하시면 좀더 편하지 않을까요?
저 그렇게 하네요~~!
댓글 감사합니다..!
네, 현재 리스트뷰에 출력해주는 array와 체크된 값을 저장하는 array[Integer형]이 따로 있습니다. 체크array의 값을 불러와 저 for문으로 삭제 해주고 있구요..그래서 문제가 되나보네요..체크된 순(?)으로 저장되다보니 뒤에서부터 순차적으로삭제되는데 문제가 있는거같습니다.
그럼 이놈을 다시 정렬해서 삭제or체크값을 넣어서 관리하는 방법으로 해야겠군요..혹시 후자는 어떤 말씀이신지 여쭤봐도될까요?
길버트공원//댓글 감사합니다. 해시가 해시맵을 말씀하시는건가용? 이건 처음보는지라..사용방법을 봐야겠습니다.
0 추천

자답입니다..

추석 전에 이미 해결했지만, 저와같은 문제를 겪은 분들이 계실까봐 남깁니다.

체크박스로 삭제 시 저처럼 앞에서부터 삭제하면 삭제될 때마다 

포지션값이 변경되기 때문에 뒤에서부터 삭제 했습니다. 

(배열오류가 발생하거나 엉뚱한 값이 삭제 되는게 그 증상이고요.)

체크값 정렬할 땐 Collections.sort(체크값저장리스트변수); 이렇게 했습니다.

이렇게 하니 오름차순으로 정렬이 되네요.

그리고 삭제 시,

for(int k=listItem.size()-1; k>-1; k--)
 {
   int pos = listItem.get(k);
    studentArr.remove(pos);
 }
listItem.clear(); //체크 삭제 후 리스트 초기화.
sAdapter.notifyDataSetChanged();

요로케 했습니다. 포지션은 0부터 시작하니 리스트 전체 사이즈-1를 하면

맨 마지막 포지션입니다. k--로 큰놈->작은놈 삭제를 하고 다 삭제 한 후엔

for문밖에서 체크값 저장한 listItem 초기화 하고 어댑터 갱신해서 삭제되고

남은 항목만 리스트에 보여줍니다. 많이 배웟네요...답변주신분들 감사합니다.

 

 

 

 

망고사탕 (5,000 포인트) 님이 2015년 10월 1일 답변
하...... 진짜 정말정말 고생하고 있는데... 자세히 설명가능하신가요??
저는 int pos = listItem.get(k); 를 하면 인트형식으로 변형할수 없다고 뜨는데 어떻게 해야하나요..?? 님 listitem은 생성자값에 String 같은것도 없나요>>??


그리고 저는 모두 삭제가 되는데.. 왜그런걸까요?? ㅋㅋ
...