Создать простую алфавитную прокрутку в ListView?
Я пытаюсь подражать функциональности в последнем приложении Music, а именно: появляется симпатичный маленький курсор, который позволяет очень быстро прокрутить до нужного исполнителя / альбома / дорожки:
Есть ли способ включить такую функциональность в ListView
в Android SDK?
6 ответов
Сделайте так, чтобы ваш адаптер списка реализовал SectionIndexer. Музыкальное приложение также использует AlphabetIndexer для выполнения некоторых тяжелых работ. Также используйте setFastScrollEnabled(true)
на фактическом ListView
чтобы включить это.
Изменить: Если вы не используете CursorAdapter, вы не сможете использовать AlphabetIndexer. Вы можете попытаться взглянуть на реализацию здесь и увидеть, насколько сложно будет адаптировать ее для работы с ArrayAdapter.
Вот подкласс 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();
}
}
setFastScrollEnabled(истина);
( http://developer.android.com/reference/android/widget/AbsListView.html)
На anddev.org я нашел этот учебник: Alphabetic FastScroll ListView - похож на Контакты
Он также содержит небольшое демо-видео
Надеюсь, поможет!
Чтобы собрать сведения об элементах, отображаемых в виде списка, вы можете сделать это:
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
albumButton.setText(songs.get(firstVisibleItem).getAlbum());
}
Разве это не немного проще? Здесь "song" - это массив объектов Song. Вы даже можете получить последний видимый элемент, добавив firstVisibleItem + visibleItemCount. Я нашел эту технику очень полезной. Тогда вы получите первую букву каждой песни. Я полагаю, серое поле с буквой в музыкальном приложении, которое вы разместили, является своего рода диалоговым окном?
В любом случае, надеюсь, это поможет. Я понимаю, что опоздал, но это для будущих людей
Я нашел отличное решение здесь... Отлично работает с огромным списком... Красиво и быстро... без времени загрузки.
@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;
}