Журнал ошибок Android для массива SectionIndexer (с быстрой прокруткой)
Я использую SectionIndexer
для ArrayAdapter
и быстрая прокрутка включена. Большинство списков работают нормально, но пара вылетает в одной точке и показывает один и тот же тип журнала.
(Пожалуйста, обратите внимание: ListView
основан на данных, введенных из таблицы MySQL. В списке около 2000 наименований. Но у SQL в списке есть "предложение", где одновременно может отображаться только 100-200. Похоже, что скроллер большого пальца естественным образом прокручивает размер 2000 элементов и не соответствует этому "предложению where". Я не верю, что это проблема PHP/MySQL, но в моем Android/Java.)
Вот журнал:
08-27 07:26:33.360: E/AndroidRuntime(9145): FATAL EXCEPTION: main
08-27 07:26:33.360: E/AndroidRuntime(9145): java.lang.ArrayIndexOutOfBoundsException: length=21; index=21-
08-27 07:26:33.360: E/AndroidRuntime(9145): at com.---.---.ItemAdapter.getPositionForSection(ItemAdapter.java:57)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.widget.FastScroller.getThumbPositionForListPosition(FastScroller.java:650)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.widget.FastScroller.onScroll(FastScroller.java:458)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.widget.AbsListView.invokeOnItemScrollListener(AbsListView.java:1325)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5067)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4205)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.view.Choreographer.doFrame(Choreographer.java:524)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.os.Handler.handleCallback(Handler.java:615)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.os.Handler.dispatchMessage(Handler.java:92)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.os.Looper.loop(Looper.java:137)
08-27 07:26:33.360: E/AndroidRuntime(9145): at android.app.ActivityThread.main(ActivityThread.java:4928)
08-27 07:26:33.360: E/AndroidRuntime(9145): at java.lang.reflect.Method.invokeNative(Native Method)
08-27 07:26:33.360: E/AndroidRuntime(9145): at java.lang.reflect.Method.invoke(Method.java:511)
08-27 07:26:33.360: E/AndroidRuntime(9145): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
08-27 07:26:33.360: E/AndroidRuntime(9145): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:558)
08-27 07:26:33.360: E/AndroidRuntime(9145): at dalvik.system.NativeStart.main(Native Method)
Вот код строки 57:
public int getPositionForSection(int section) {
return alphaIndexer.get(sections[section]);
}
Кроме того, вот еще код в адаптере:
alphaIndexer = new HashMap<String, Integer>();
int size = objects.length;
for (int i = 0; i < size; i++) {
ItemObject it = objects[i];
String name = it.name;
String s = name.substring(0, 1);
s = s.toUpperCase();
if (!alphaIndexer.containsKey(s)) {
alphaIndexer.put(s, i);
}
}
Set<String> sectionLetters = alphaIndexer.keySet();
ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
Collections.sort(sectionList);
sections = new String[sectionList.size()];
// sectionList.toArray(sections);
for (int i = 0; i < sectionList.size(); i++)
sections[i] = sectionList.get(i);
public int getSectionForPosition(int position)
{
int closestIndex = 0;
int latestDelta = Integer.MAX_VALUE;
for(int i=0; i < sections.length; i++) {
Log.d("Sections Length: ", String.valueOf(sections.length));
int current = alphaIndexer.get(sections[i]);
if(current == position) {
//If position matches an index, return it immediately
return i;
} else if(current < position) {
//Check if this is closer than the last index we inspected
int delta = position - current;
if(delta < latestDelta) {
closestIndex = i;
latestDelta = delta;
}
}
}
return closestIndex;
}
public Object[] getSections() {
return sections;
}
2 ответа
Ее мой последний код, который работал:
int size = objects.length;
for (int i = 0; i < size; i++) {
ItemObject it = objects[i];
String name = it.name;
String s = name.substring(0, 1);
s = s.toUpperCase();
if (!alphaIndexer.containsKey(s)) {
alphaIndexer.put(s, i);
}
}
Set<String> sectionLetters = alphaIndexer.keySet();
ArrayList<String> sectionList = new ArrayList<String>(sectionLetters);
Collections.sort(sectionList);
sections = new String[sectionList.size()];
for (int i = 0; i < sectionList.size(); i++) {
sections[i] = sectionList.get(i);
}
}
public int getPositionForSection(int section) {
int maxSize = sections.length - 1;
if (section > maxSize) {
return 0;
} else {
return alphaIndexer.get(sections[section]);
}
}
public int getSectionForPosition(int position)
{
int closestIndex = 0;
int latestDelta = Integer.MAX_VALUE;
for (int i = 0; i < sections.length; i++) {
int current = alphaIndexer.get(sections[i]);
if (current == position) {
// If position matches an index, return it immediately
return i;
} else if (current < position) {
// Check if this is closer than the last index we inspected
int delta = position - current;
if (delta < latestDelta) {
closestIndex = i;
latestDelta = delta;
}
}
}
return closestIndex;
}
Пожалуйста, смотрите https://code.google.com/p/android/issues/detail?id=33293
Они предлагают проверить границы массива:
@Override
public int getPositionForSection(int section) {
if (section > sections.length - 1) {
return mItems.size() - 1;
} else {
return alphaIndexer.get(sections[section]);
}
}
Документация для обоих методов getPositionForSection
а также getSectionForPosition
говорит:
Если начальная позиция секции находится за пределами границ адаптера, положение должно быть обрезано, чтобы соответствовать размеру адаптера.