Создать простую алфавитную прокрутку в ListView? - PullRequest
15 голосов
/ 26 февраля 2011

Я хочу подражать функциональности в последнем музыкальном приложении, а именно: появляется симпатичный маленький курсор, который позволяет очень быстро прокрутить до исполнителя / альбома / трека, который они ищут:

Regular Scrolling

Есть ли способ включить такую ​​функцию в ListView в Android SDK?

Ответы [ 6 ]

16 голосов
/ 26 февраля 2011

У вашего адаптера списка есть SectionIndexer . Музыкальное приложение также использует AlphabetIndexer для выполнения некоторых тяжелых работ. Также используйте setFastScrollEnabled(true) для фактического ListView, чтобы включить это.

Редактировать : Если вы не используете CursorAdapter, вы не сможете использовать AlphabetIndexer. Вы можете попытаться посмотреть на реализацию здесь и увидеть, насколько сложно будет адаптировать ее для работы с ArrayAdapter.

4 голосов
/ 12 апреля 2013

Вот подкласс ArrayAdapter, который я использую.Обратите внимание, что objects, который я передаю, уже отсортирован по алфавиту, с Collections.sort(objects).

class SectionIndexingArrayAdapter<T> extends ArrayAdapter<T> implements
        SectionIndexer {

    HashMap<String, Integer> sectionsMap = new HashMap<String, Integer>();
    ArrayList<String> sectionsList = new ArrayList<String>();

    ArrayList<Integer> sectionForPosition = new ArrayList<Integer>();
    ArrayList<Integer> positionForSection = new ArrayList<Integer>();

    public SectionIndexingArrayAdapter(Context context, int textViewResourceId,
            List<T> objects) {
        super(context, textViewResourceId, objects);

        // Note that List<T> objects has already been sorted alphabetically
        // e.g. with Collections.sort(objects) **before** being passed to
        // this constructor.

        // Figure out what the sections should be (one section per unique
        // initial letter, to accommodate letters that might be missing,
        // or characters like ,)
        for (int i = 0; i < objects.size(); i++) {
            String objectString = objects.get(i).toString();
            if (objectString.length() > 0) {
                String firstLetter = objectString.substring(0, 1).toUpperCase();
                if (!sectionsMap.containsKey(firstLetter)) {
                    sectionsMap.put(firstLetter, sectionsMap.size());
                    sectionsList.add(firstLetter);
                }
            }
        }

        // Calculate the section for each position in the list.
        for (int i = 0; i < objects.size(); i++) {
            String objectString = objects.get(i).toString();
            if (objectString.length() > 0) {
                String firstLetter = objectString.substring(0, 1).toUpperCase();
                if (sectionsMap.containsKey(firstLetter)) {
                    sectionForPosition.add(sectionsMap.get(firstLetter));
                } else
                    sectionForPosition.add(0);
            } else
                sectionForPosition.add(0);
        }

        // Calculate the first position where each section begins.
        for (int i = 0; i < sectionsMap.size(); i++)
            positionForSection.add(0);
        for (int i = 0; i < sectionsMap.size(); i++) {
            for (int j = 0; j < objects.size(); j++) {
                Integer section = sectionForPosition.get(j);
                if (section == i) {
                    positionForSection.set(i, j);
                    break;
                }
            }
        }
    }

    // The interface methods.

    public int getPositionForSection(int section) {
        return positionForSection.get(section);
    }

    public int getSectionForPosition(int position) {
        return sectionForPosition.get(position);
    }

    public Object[] getSections() {
        return sectionsList.toArray();
    }
}
3 голосов
/ 26 февраля 2011
2 голосов
/ 22 октября 2011

Чтобы собрать сведения об элементах, отображаемых в виде списка, вы можете сделать это:

@Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {

            albumButton.setText(songs.get(firstVisibleItem).getAlbum());

        }

Разве это не проще? Здесь «песни» - это массив объектов Song. Вы даже можете получить последний видимый элемент, добавив firstVisibleItem + visibleItemCount. Я нашел эту технику очень полезной. Тогда вы получите первую букву каждой песни. Я полагаю, серое поле с буквой в музыкальном приложении, которое вы разместили, является своего рода диалоговым окном?

В любом случае, надеюсь, это поможет. Я понимаю, что опоздал, но это для будущих людей

2 голосов
/ 26 февраля 2011

На anddev.org я нашел этот учебник: Алфавитный FastScroll ListView - похож на Контакты

Он также содержит короткий демонстрационный видеоролик

Надеюсь, это поможет!

1 голос
/ 02 ноября 2015

Я нашел отличное решение здесь ... Отлично работает с огромным списком ... Красиво и быстро ... без времени загрузки.

@Override
public int getPositionForSection(int section)
{
    log.info("Get position for section");

    for (int i = 0; i < this.getCount(); i++)
    {
        if (this.getItem(i).length() > 0)
        {
            String item = this.getItem(i).toUpperCase();
            if (item.charAt(0) == sections.charAt(section))
            {
                return i;
            }
        }
    }
    return 0;
}

@Override
public int getSectionForPosition(int arg0)
{
    log.info("Get section");

    return 0;
}

@Override
public Object[] getSections()
{
    log.info("Get sections");

    String[] sectionsArr = new String[sections.length()];

    for (int i = 0; i < sections.length(); i++)
    {
        sectionsArr[i] = "" + sections.charAt(i);
    }
    return sectionsArr;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...