1

状況

通常とヘッダーの2つのビュータイプを持つ複数選択モードのListViewがあります。名前と電子メールを含むカーソルを取得して連絡先アプリからデータを読み込み、AlphabetIndexer クラスを利用します。私のアダプターは、SimpleCursorAdapter クラスを拡張し、SectionIndexer を実装します。さらに、アダプターの getCount() メソッドをオーバーライドして、カーソルの数 + セクションの数を返すようにします。さらに、私のレイアウトは正しく、ユーザーの操作に応じて onListItemClickListener で項目が強調表示されます。

問題

ただし、[すべてチェック] ボタンですべての項目を強調表示したいのですが、コードではそれができません。

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() をログに記録すると、このリストにはすべてのアイテムが含まれます。レイアウトは確認していません。

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

そのため、状態は変更されますが、レイアウトは変更されません。

55 の連絡先と 20 のセクション ヘッダーを含むリストがあります。位置 0 で Select All Button アイテムを実行すると、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;
}
4

1 に答える 1

0

編集

問題は、メソッドをあちこちで呼び出していることだと思いますsuper。これは、私の意見では、SimpleCursorAdapterhas のデフォルトの動作 (選択の強調表示を含む) が最初のsize of the cursor項目にのみ適用されることを意味します。

つまり、選択した行の強調表示は のデフォルトの「機能」Adapterではなく、明示的に実装する必要があるものです。

SimpleCursorAdapter Cursorハイライト機能が組み込まれていますが、のサイズに等しい数のアイテムに対してのみハイライトが行われます。

メソッドで自分でビューを手動で管理する以外に、これを変更する方法がわかりませんgetView(つまり、ビューの背景を変更して自分でハイライトを行います)。

于 2014-09-29T06:39:19.873 に答える