【问题标题】:Indexoutofboundsexception with listview列表视图的Indexoutofboundsexception
【发布时间】:2011-10-20 11:22:40
【问题描述】:

我刚刚得到一个奇怪的 indexoutofboundsexception,我似乎无法重现。好像和我的listactivity有关:

java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
at java.util.ArrayList.get(ArrayList.java:311)
at android.widget.HeaderViewListAdapter.getView(HeaderViewListAdapter.java:229)
at android.widget.AbsListView.obtainView(AbsListView.java:1410)
at android.widget.ListView.makeAndAddView(ListView.java:1802)
at android.widget.ListView.fillDown(ListView.java:727)
at android.widget.ListView.fillSpecific(ListView.java:1359)
at android.widget.ListView.layoutChildren(ListView.java:1633)
at android.widget.AbsListView.onLayout(AbsListView.java:1263)
at android.view.View.layout(View.java:7088)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1249)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1125)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1042)
at android.view.View.layout(View.java:7088)
at android.widget.FrameLayout.onLayout(FrameLayout.java:334)
at android.view.View.layout(View.java:7088)
at android.widget.FrameLayout.onLayout(FrameLayout.java:334)
at android.view.View.layout(View.java:7088)
at android.widget.FrameLayout.onLayout(FrameLayout.java:334)
at android.view.View.layout(View.java:7088)
at android.widget.FrameLayout.onLayout(FrameLayout.java:334)
at android.view.View.layout(View.java:7088)
at android.widget.FrameLayout.onLayout(FrameLayout.java:334)
at android.view.View.layout(View.java:7088)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1249)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1125)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1042)
at android.view.View.layout(View.java:7088)
at android.widget.FrameLayout.onLayout(FrameLayout.java:334)
at android.view.View.layout(View.java:7088)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1249)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1125)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1042)
at android.view.View.layout(View.java:7088)
at android.widget.FrameLayout.onLayout(FrameLayout.java:334)
at android.view.View.layout(View.java:7088)
at android.widget.FrameLayout.onLayout(FrameLayout.java:334)
at android.view.View.layout(View.java:7088)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1056)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1752)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

我认为这可能与我添加/删除页脚视图的方式有关。这是代码:

private void setLoadMoreFooter() {
    resumeProgressBarAnimation(progressbar);
    if (getListView().getFooterViewsCount() != 0 || currentCategory == null) {
        try {
            getListView().removeFooterView(footerView);
        } catch (ClassCastException e) {
        }
    }
    cursor = getVouchersFromDatabase();
    Log.d(TAG, "Determining FOOTER status:\nCurrent page size: " + cursor.getCount()%10 + "\nCurrent category: " + currentCategory + "\nPage: " + currentCategory.getPage());
    // Add footer if there are 10 vouchers on the current page
    if (cursor.getCount()%10 == 0 && currentCategory != null) {
        getListView().addFooterView(footerView, null, true);
    }
    else if (currentCategory.getPage() >= 2 && cursor.getCount()%10 != 0) {
        getListView().addFooterView(footerView, null, false);
    }
}

翻看源码,错误似乎是在headerviewlistadapter的getview方法中抛出的这一行:

return mHeaderViewInfos.get(position).view;

有谁知道这可能是什么原因?

【问题讨论】:

标签: android


【解决方案1】:

我通过确保在数据集更改时通知适配器来解决此问题。 在我的情况下,数据被另一个线程更改,在 listview 检查数据是否正确之后。 在查看 listview 源代码后。我在这里发现异常抛出:

    public View More ...getView(int position, View convertView, ViewGroup parent) {
    // Header (negative positions will throw an ArrayIndexOutOfBoundsException)
    int numHeaders = getHeadersCount();
    if (position < numHeaders) {
        return mHeaderViewInfos.get(position).view;
    }

    // Adapter
    final int adjPosition = position - numHeaders;
    int adapterCount = 0;
    if (mAdapter != null) {
        adapterCount = mAdapter.getCount();
        if (adjPosition < adapterCount) {
            return mAdapter.getView(adjPosition, convertView, parent);
        }
    }

    // Footer (off-limits positions will throw an ArrayIndexOutOfBoundsException)
    return mFooterViewInfos.get(adjPosition - adapterCount).view;
}

所以你可以看到 mFooterViewInfos.get(adjPosition - adapterCount).view 抛出了 Indexoutofboundsexception。因为这个位置比listview想象的要大。

您需要做的是找出导致此异常的视图。并确保一旦数据更改立即通知适配器!

【讨论】:

  • 这对我有帮助,我的问题解决了,原因是数据是全局变量,并且在网络请求中的某处被更改。 (只有android 6.0 会报这个bug,所以我觉得刷新机制和以前有些不同。)
【解决方案2】:

查看 google 网站上的代码后,我看到了许多不同类型的初始化和对 mHeaderViewInfos 的访问,但实际上我没有看到任何添加到其中的内容。投入一些调试点并对其进行跟踪可能会有所帮助。祝你好运!

【讨论】:

  • 感谢您的回复。我尝试在 onstop 隐藏 listview 并使其在 onrestart 时再次可见,但从那以后我就再也没有遇到过。
【解决方案3】:

使用addFooterView(footerView)就可以解决这个问题了。

【讨论】:

    【解决方案4】:

    @Kevin Qiu 隐藏东西的提示很有帮助。我只需要隐藏标题视图,而不是整个列表。这是对我有用的代码,假设标题视图名为 mHeaderView
    @Override public void onStop() { super.onStop(); mHeaderView.setVisibility(View.GONE);// fixes weird bug with header view }

    为了确保它在您切换到其他应用后显示出来,请执行以下代码。
    @Override public void onStart() { if(mHeaderView.getVisibility() == View.GONE) mHeaderView.setVisibility(View.VISIBLE); super.onStart(); }

    【讨论】:

      【解决方案5】:

      在使用带有页眉视图或页脚视图的 ListView 来添加/删除时,我遇到了同样的问题。所以在 Stack Overflow 上尝试了不同的方法,我找到了一个解决方法来忽略这些错误,处理 dispatchDraw 方法如下。

      public class CustomListView extends ListView{
      
         @Override
         protected void dispatchDraw(Canvas canvas) {
            try {
                super.dispatchDraw(canvas);
            } catch (IndexOutOfBoundsException e) {
                Log.e("luna", "Ignore list view error ->" + e.toString());
            }
         }
      }
      

      希望对你有帮助。

      请参考此链接How to debug Android java.lang.IndexOutOfBoundsException HeaderViewListAdapter.java line

      玩得开心@.@

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-06
        • 2017-01-13
        • 2017-05-14
        • 2021-08-06
        • 1970-01-01
        • 2015-06-02
        相关资源
        最近更新 更多