2012-08-27 40 views
0

我使用SectionIndexer一个ArrayAdapter并启用快速滚动。大多数列表工作正常,但是有一些列表在同一点出现故障并显示相同类型的日志。 (请注意:ListView基于从MySQL表输入的数据,该列表包含大约2000个项目,但列表中的SQL有一个“where子句”,其中只有100-200个可能一次显示。它看起来拇指滚动自然滚动2000项目的大小,并不对应于这个“where子句”。我不相信这是一个PHP/MySQL的问题,但在我的Android/Java。)Android的错误日志中SectionIndexer阵列(快速滚动)

这里被记录:

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; 
} 
+0

你能否提供关于何时发生这种情况的更多细节(例如在列表末尾滚动,在数据重置等之后进行滚动)? – Luksprog

+0

没有模式;有时中间,有时结束。我确实通过注销部分ArrayList来确认输入了预期的变量;我能想到的唯一的事情是数据可能有问题,而不是代码?我将在接下来检查我的餐桌项目。 – KickingLettuce

+0

@Luksprog更新:“MySQL”表没有隐藏数据或任何异常。有2个20的列表崩溃。他们都来自同一张桌子,有不同的'where'条款。 1几乎崩溃在底部,另一半大约下降50%。正常滚动时会崩溃,而不是使用thumbscroller。一个列表在'SectionIndexer'中有7个项目。撞到第八名时崩溃。每次使用滚动手势时(通过'Log'),我都会打印出'ArrayList';它在ArrayList中只显示了7个,直到碰撞说有8个项目。我无法打印出第8项。 – KickingLettuce

回答

1

她是我这工作的最终代码:

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; 
    } 
+0

不错的一个,关键在'getPositionForSection()',这使得事情工作正常。 – astuter

0

请参阅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]); 
    } 
} 

两种方法getPositionForSectiongetSectionForPosition文档说:

如果该部分的起始位置是适配器范围之外, 位置必须被裁剪落入适配器的尺寸范围内。