Индексатор разделов получить раздел для возврата позиции 0

В моем проекте у меня есть класс, который расширяется ArrayAdapter<String> и реализует SectionIndexer, При реализации методов getPositionForSection а также getSectionForPosition Я обнаружил странное поведение.

Почему секционный индексатор работает правильно, когда getSectionForPosition возвращает 0?

public int getSectionForPosition(int position) {
    return 0;
}

эта реализация используется во многих руководствах, например:

http://androidopentutorials.com/android-listview-fastscroll/

http://www.survivingwithandroid.com/2012/12/android-listview-sectionindexer-fastscroll.html

Документация говорит, что

Учитывая позицию в адаптере, возвращает индекс соответствующего раздела в массиве объектов раздела.

так что если в моем списке 5 элементов, начинающихся с буквы "А", а некоторые элементы начинаются с буквы "В", то getSectionForPosition(5) должен вернуть 1.

2 ответа

Решение

Хотя основной функционал sectionIndexer (прокрутка индексов разделов при перетаскивании большого пальца полосы прокрутки) не затрагивается, возвращая константу в методе getSectionForPosition может привести к неправильному поведению расположения полосы прокрутки при пролистывании списка (например, полоса прокрутки, выходящая из окна по оси Y).

Очевидно, это неправильное поведение происходит только тогда, когда список или отдельные разделы превышают определенную длину, поэтому для более коротких списков может показаться, что индексатор работает правильно (но на самом деле это не так). Я столкнулся с этим неправильным поведением в больших списках, когда возвращал константу в вышеупомянутом методе несколько раз, и исправил ее getSectionForPosition правильно.


Тем не менее, поскольку это может быть интересно для других, я могу предоставить пример реализации этого метода. Позволять azIndexer быть HashMap содержащий правильный section -> position отображение моих показателей и listItems быть пунктами, устроенными адаптером. Следующее строит position -> sectionIndex отображение хранится в positionIndexer,

List<Integer> values = new ArrayList();
for (int i : azIndexer.values()) {
    values.add(i);
}
values.add(listItems.size()-1);
Collections.sort(values);

int k = 0;
int z = 0;
for(int i = 0; i < values.size()-1; i++) {
    int temp = values.get(i+1);
    do {
        positionIndexer.put(k, z);
        k++;
    } while(k < temp);
    z++;
}

который затем будет использован в getSectionForPosition метод:

@Override
public int getSectionForPosition(int position) {
    return positionIndexer.get(position);
}

Ваш метод обратного вызова getPositionForSection(int section) должен быть реализован, чтобы дать правильную позицию, которая используется setSelection для возврата правильной позиции, в которой вы хотите прокрутить касание SectionIndexer на правой стороне.

Убедитесь, что вы делаете это

this.setSelection(((SectionIndexer) getAdapter()) .getPositionForSection(currentPosition));

Вам нужно реализовать два метода обратного вызова

@Override
public Object[] getSections() { 
  Log.d("ListView", "Get sections"); 
  String[] sectionsArr = new String[sections.length()]; 
  for (int i=0; i < sections.length(); i++) 
  sectionsArr[i] = "" + sections.charAt(i);

   return sectionsArr; 
 }

Этот последний обратный звонок, и вы сделали здесь

@Override 
public int getPositionForSection(int section){ 
  Log.d("ListView", "Get position for section"); 
  for (int i=0; i < this.getCount(); i++) { 
  String item = this.getItem(i).toLowerCase(); 
  if (item.charAt(0) == sections.charAt(section)) 

 return i; 
} 

return 0; 
}
Другие вопросы по тегам