2011-01-04 7 views
8

사용자 지정 BaseAdapter를 사용하여 ListView에 항목을 표시하고 있습니다. 항목은 ArrayList에 보관 된 문자열입니다.사용자 지정 BaseAdapter를 사용하여 ListView에서 항목 삭제

목록 항목에는 삭제 버튼이 있습니다 (큰 빨간 X). ArrayList에서 해당 항목을 제거하고 ListView에 업데이트를 알리고 싶습니다.

그러나 구현 한 모든 구현에는 신비한 위치 번호가 지정되어 있습니다. 예를 들어 항목 2의 삭제 버튼을 클릭하면 항목 5가 삭제됩니다. 그것은 거의 전적으로 무작위 인 것으로 보인다.

한 가지주의 할 점은 요소가 반복 될 수 있지만 동일한 순서로 유지되어야한다는 것입니다. 예를 들어, 나는 요소 3으로, "아일랜드어"두 번 가질 수 있고 7

내 코드는 다음과 같습니다 :

private static class ViewHolder { 
     TextView lang; 
     int position; 
} 

public View getView(final int position, View convertView, ViewGroup parent) { 
    ViewHolder holder; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.language_link_row, null); 
     holder = new ViewHolder(); 
     holder.lang = (TextView)convertView.findViewById(R.id.language_link_text); 
     holder.position = position; 

     final ImageView deleteButton = (ImageView) 
       convertView.findViewById(R.id.language_link_cross_delete); 
     deleteButton.setOnClickListener(this); 

     convertView.setTag(holder); 
     deleteButton.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    holder.lang.setText(mLanguages.get(position)); 

    return convertView; 
} 

나중에 태그를 잡는하여 삭제 된 요소의 위치를 ​​검색하려고 시도하지만 항상 목록에서 잘못된 위치. 여기 주어진 위치에 눈에 띄는 패턴이 없으며, 항상 랜덤하게 보입니다.

// The delete button's listener 
public void onClick(View v) { 

    ViewHolder deleteHolder = (ViewHolder) v.getTag(); 
    int pos = deleteHolder.position; 

    ... 
    ... 
    ... 
} 

난 그냥 ArrayList를에서 항목을 삭제하고있는 ListView가 자동으로 업데이트가 아주 행복 할 것이다, 그러나 내가 갖는 위치 그래서 난 할 수 없어 올바르지 않습니다.

먼저 getView 메서드 내에서 deleteButton clickListener를 사용하고 'position'을 사용하여 값을 삭제했지만 동일한 문제가있었습니다.

의견이 있으면 감사하겠습니다.

답변

5

매번 위치를 설정해야합니다. 구현은 뷰 생성시 위치 만 설정합니다. 그러나 뷰가 재활용 될 때 (convertView가 null이 아닌 경우) 위치는 올바른 값으로 설정되지 않습니다.

public View getView(final int position, View convertView, ViewGroup parent) { 
    ViewHolder holder; 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.language_link_row, null); 
     holder = new ViewHolder(); 
     holder.lang = (TextView)convertView.findViewById(R.id.language_link_text); 

     final ImageView deleteButton = (ImageView) 
       convertView.findViewById(R.id.language_link_cross_delete); 
     deleteButton.setOnClickListener(this); 

     convertView.setTag(holder); 
     deleteButton.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    holder.lang.setText(mLanguages.get(position)); 
    holder.position = position; 
    return convertView; 
} 
+1

훌륭하게, 감사합니다. 내가 어리석은 그런 문제에 너무 오랫동안 보냈다는 것을 믿을 수 없다. 관심있는 사람들을 위해 별도의 답변으로 일반적인 솔루션을 추가했습니다. – HXCaine

0

당신이 OnItemClickListener 인터페이스를 구현하고, onItemClick 방법에서 항목을 삭제해야합니다, 방법의 하나 개의 매개 변수는 위치입니다.

+1

그는 청취자가 적합하지 않도록 버튼이 있습니다. 해당 리스너는 전체 목록 요소가 click 이벤트를받는 경우에만 작동합니다. –

0

내 최종 솔루션은 그렉에 의해 허용 대답을 사용하는 것이었다 다음과 같은 : (이 생성자에서 빈으로 초기화된다) 키와 같은 항목의 위치와는 HashMap에서

  • 스토어 홀더

    개인용 HashMap mHolders; OnClickListener를 방법으로

  • 사용이 :

public void onClick(View v) { 
    ViewHolder deleteHolder = (ViewHolder) v.getTag(); 
    int pos = deleteHolder.position; 
    mHolders.remove(pos);

ViewHolder currentHolder; 

    // Shift 'position' of remaining languages 
    // down since 'pos' was deleted 
    for(int i=pos+1; i<getCount(); i++){ 
     currentHolder = mHolders.get(i); 
     currentHolder.position = i-1; 
    } 
    mLanguages.remove(pos); 
    notifyDataSetChanged(); 
} 
[이상한 서식을 용서하십시오. 코드 임베딩이 제대로 작동하지 않습니다.]

관련 문제