0

を使用SectionIndexerしてArrayAdapterおり、高速スクロールが有効になっています。ほとんどのリストは問題なく動作しますが、いくつかが同じ時点でクラッシュし、同じ種類のログが表示されます。

(注: これListViewは、MySQL テーブルから入力されたデータに基づいています。リストには約 2000 項目があります。しかし、リスト内の SQL には、一度に 100 ~ 200 個しか表示されない「where 句」があります。サム スクローラーに表示されます。自然に 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;
}
4

2 に答える 2

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;
    }
于 2012-08-29T15:52:22.933 に答える
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]);
    }
}

両方の方法のドキュメントには、getPositionForSection次のように記載されていgetSectionForPositionます。

セクションの開始位置がアダプターの境界の外にある場合、アダプターのサイズ内に収まるように位置をクリップする必要があります。

于 2014-02-08T11:22:45.663 に答える