2014-09-29 5 views
1

상황

두 가지보기 유형 인 일반 및 헤더가있는 다중 선택 모드 ListView가 있습니다. 이름과 이메일이있는 커서를 가져 와서 AlphabetIndexer 클래스를 사용하여 연락처 앱에서 데이터를로드합니다. 내 어댑터 SimpleCursorAdapter 클래스를 확장하고 SectionIndexer 구현합니다. 또한 커서의 개수 + 섹션 수를 반환하도록 어댑터의 getCount() 메서드를 재정의합니다. 또한 사용자 레이아웃에 따라 레이아웃이 정확하고 항목이 onListItemClickListener에서 강조 표시됩니다.setListItemChecked가 목록 항목을 모두 강조 표시하지 않음

문제

그러나, 나는 확인 모든 항목 모든 버튼을 강조하고 싶지만 코드는 그렇게하지 못합니다.

for (int i = 0; i <= adapter.getCount() - 1; i++) { 
      adapter.getItem(i); 
      if (adapter.getItemViewType(i) == InviteContactListAdapter.TYPE_NORMAL) { 
       listView.setItemChecked(i, true); 
      } 

     } 

그런 다음 올바르게 cursror.getCount()보다 작은 위치에있는 항목의 레이아웃을 변경하고는 ListView.getCheckedItemPositions()를 로그인 index.I 더 큰과 나머지를 표시하기를 거부하고이 목록에 포함 레이아웃이 점검되지 않은 항목을 포함하여 모든 항목.

Log.d("checkedItems:", listView.getCheckedItemPositions()): 

따라서 상태는 변경되지만 레이아웃은 변경되지 않습니다.

55 개의 연락처와 20 개의 섹션 헤더가있는 목록이 있습니다. 내가 Select All 버튼을 실행하면 위치 0 ... 55의 항목이 강조 표시됩니다. 56에서 75까지의 항목은 강조 표시되지 않고 선택 표시 만 나타납니다.

코드

public class InviteContactListAdapter extends SimpleCursorAdapter implements 
    SectionIndexer { 

public static final int TYPE_HEADER = 1; 
public static final int TYPE_NORMAL = 0; 
public static final int TYPE_COUNT = 2; 

private AlphabetIndexer indexer; 

private int[] usedSectionNumbers; 
private Map<Integer, Integer> sectionToPosition; 
private Context context; 
private HashMap<Integer, Integer> sectionToOffset; 

public InviteContactListAdapter(Context context, int layout, Cursor c, 
     String[] from, int[] to) { 
    super(context, layout, c, from, to, 0); 

    ArrayList<String> stringCollection = new ArrayList<String>(); 
    Character firstLetter; 
    String firstLetterAsString; 
    while (c.moveToNext()) { 
     firstLetter = c.getString(
       c.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)) 
       .charAt(0); 
     firstLetter = Character.toUpperCase(firstLetter); 
     firstLetterAsString = firstLetter.toString(); 
     if (!stringCollection.contains(firstLetterAsString) 
       && Character.isLetter(firstLetter)) { 
      stringCollection.add(firstLetterAsString); 
     } 
    } 
    Collections.sort(stringCollection); 
    String alphabet = " "; 
    for (String s : stringCollection) { 
     alphabet = alphabet + s; 
    } 
    c.moveToFirst(); 
    Log.d("length", "" + alphabet.length()); 

    this.context = context; 
    indexer = new AlphabetIndexer(c, 
      c.getColumnIndexOrThrow(ContactsContract.Data.DISPLAY_NAME), 
      alphabet); 
    sectionToPosition = new TreeMap<Integer, Integer>(); 
    sectionToOffset = new HashMap<Integer, Integer>(); 

    final int count = super.getCount(); 

    int i; 
    for (i = count - 1; i >= 0; i--) { 
     sectionToPosition.put(indexer.getSectionForPosition(i), i); 
    } 

    i = 0; 
    usedSectionNumbers = new int[sectionToPosition.keySet().size()]; 

    for (Integer section : sectionToPosition.keySet()) { 
     sectionToOffset.put(section, i); 
     usedSectionNumbers[i] = section; 
     i++; 
    } 

    for (Integer section : sectionToPosition.keySet()) { 
     sectionToPosition.put(section, sectionToPosition.get(section) 
       + sectionToOffset.get(section)); 
    } 
    Log.d("", ""); 
} 

@Override 
public int getCount() { 
    if (super.getCount() != 0) { 
     return super.getCount() + usedSectionNumbers.length; 
    } 

    return 0; 
} 

@Override 
public Object getItem(int position) { 
    if (getItemViewType(position) == TYPE_NORMAL) { 
     return super.getItem(position 
       - sectionToOffset.get(getSectionForPosition(position)) - 1); 
    } 
    return null; 
} 

@Override 
public int getPositionForSection(int section) { 
    if (!sectionToOffset.containsKey(section)) { 
     int i = 0; 
     int maxLength = usedSectionNumbers.length; 

     while (i < maxLength && section > usedSectionNumbers[i]) { 
      i++; 
     } 
     if (i == maxLength) 
      return getCount(); 

     return indexer.getPositionForSection(usedSectionNumbers[i]) 
       + sectionToOffset.get(usedSectionNumbers[i]); 
    } 
    return indexer.getPositionForSection(section) 
      + sectionToOffset.get(section); 
} 

@Override 
public int getSectionForPosition(int position) { 
    int i = 0; 
    int maxLength = usedSectionNumbers.length; 
    while (i < maxLength 
      && position >= sectionToPosition.get(usedSectionNumbers[i])) { 
     i++; 
    } 
    return usedSectionNumbers[i - 1]; 
} 

@Override 
public Object[] getSections() { 
    return indexer.getSections(); 
} 

// nothing much to this: headers have positions that the sectionIndexer 
// manages. 
@Override 
public int getItemViewType(int position) { 
    if (position == getPositionForSection(getSectionForPosition(position))) { 
     return TYPE_HEADER; 
    } 
    return TYPE_NORMAL; 
} 

@Override 
public int getViewTypeCount() { 
    return TYPE_COUNT; 
} 

// return the header view, if it's in a section header position 
@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final int type = getItemViewType(position); 
    LayoutInflater inflater = LayoutInflater.from(context); 
    if (type == TYPE_HEADER) { 
     if (convertView == null) { 
      convertView = inflater.inflate(
        R.layout.list_item_alphabet_section_header, parent, 
        false); 
     } 
     ((TextView) convertView.findViewById(R.id.letter_header)) 
       .setText((String) getSections()[getSectionForPosition(position)]); 

     return convertView; 
    } 
    return super.getView(
      position - sectionToOffset.get(getSectionForPosition(position)) 
        - 1, convertView, parent); 
} 

// these two methods just disable the headers 
@Override 
public boolean areAllItemsEnabled() { 
    return false; 
} 

@Override 
public boolean isEnabled(int position) { 
    if (getItemViewType(position) == TYPE_HEADER) { 
     return false; 
    } 
    return true; 
} 

답변

0

편집 나는 문제가 당신이 (내 의견에 SimpleCursorAdapter의 기본 동작한다는 것을 의미하는 모든 장소에 걸쳐 super 메소드를 호출되는 것 같아요

하는 선택 사항 강조 표시 포함)은 첫 번째 size of the cursor 항목에만 적용됩니다. 선택한 행을 강조 즉

, 기본Adapter의 "기능",하지만 당신은 명시 적으로 구현해야합니다 오히려 일이 아니다. SimpleCursorAdapter이 강조 "내장"을 가지고 있지만

, 그것은 단지 Cursor의 크기와 동일한 항목의 번호를 그렇게.

getView 방법으로 수동으로 직접보기를 관리하는 것 (즉,보기의 배경을 변경하여 자신을 강조 표시하는 것)을 어떻게 변경할 수 있는지는 알 수 없습니다.

+0

감사합니다. Bogdan,하지만 그건 사실이 아닙니다. 나는 그것을 3 배로 체크했고 그것은 절대적으로 정확하다. 나는 어딘가에 기본 클래스에서 코드가 커서의 수를 어댑터의 수를 사용하지 않는 것 같아요. 그러나 나는 그것을 발견 할 수 없다. – dTod

+0

@dTod이 문제에 대한 내 의견을 검토했으며, 지금 도움이되기를 바랍니다 :) –