Создать простую алфавитную прокрутку в 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();
}
}
Ответ 3
setFastScrollEnabled (истина);
(http://developer.android.com/reference/android/widget/AbsListView.html)
Ответ 4
На anddev.org Я нашел этот учебник: Алфавитный список FastScroll ListView - аналогично контактам
Он также содержит короткое демо-видео
Надеюсь, что это поможет!
Ответ 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;
}