Создать простую алфавитную прокрутку в ListView?

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

"Super Scrolling"Regular Scrolling

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

Ответы

Ответ 1

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

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

Ответ 2

Вот подкласс ArrayAdapter, который я использую. Обратите внимание, что objects я pass in уже отсортирован в алфавитном порядке, с 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();
    }
}

Ответ 5

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

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

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

        }

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

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

Ответ 6

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

@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;
}