Kevin Qiu
Kevin Qiu

Reputation: 1626

Indexoutofboundsexception with listview

I just got a strange indexoutofboundsexception that I can't seem to reproduce. It seems to be related to my 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)

I'm thinking it might be related to how I add/remove my footerview. Here is the code for that:

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);
    }
}

Looking through the source code, the error seems to be thrown in the headerviewlistadapter's getview method at this line:

return mHeaderViewInfos.get(position).view;

Does anyone know what the cause of this might be?

Upvotes: 3

Views: 7952

Answers (5)

Luna Kong
Luna Kong

Reputation: 3155

I met the same issue when using ListView with header view or footer view to add/remove. So tried different approaches on Stack Overflow, I found a workaround solution to ignore these errors which to handle the dispatchDraw method as below.

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());
      }
   }
}

Hope that can help u.

Please refer to this link How to debug Android java.lang.IndexOutOfBoundsException HeaderViewListAdapter.java line

Have Fun@.@

Upvotes: 0

OverLook
OverLook

Reputation: 21

I solve this problem by make sure notify adapter when data set is changed. In my case,data was changed by another thread,after listview check if data was right. After look into listview source. I fount the exception throw out here:

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

So you can see that mFooterViewInfos.get(adjPosition - adapterCount).view throw a Indexoutofboundsexception. Because the position is larger than listview thought it will be.

What you have to do is find out which view cause this exception. And make sure once the data is changed notify the adapter immediately!

Upvotes: 1

ShawnV
ShawnV

Reputation: 168

@Kevin Qiu the hint to hide stuff helped. I only had to hide the headerview, not the whole list. Here's the code that worked for me, assuming that the header view is named mHeaderView
@Override public void onStop() { super.onStop(); mHeaderView.setVisibility(View.GONE);// fixes weird bug with header view }

And to Make sure it shows up after you switch to a different app, do the code below.
@Override public void onStart() { if(mHeaderView.getVisibility() == View.GONE) mHeaderView.setVisibility(View.VISIBLE); super.onStart(); }

Upvotes: 0

codeWalker
codeWalker

Reputation: 1

Use addFooterView(footerView) it will be solve this problem.

Upvotes: 0

Sababado
Sababado

Reputation: 2532

After looking through the code on the google site, I see a lot of different types of initializations and accesses to the mHeaderViewInfos, but I don't actually see anything being added to it. It might benefit to throw in some debug points and trace it through. Good luck!

Upvotes: 0

Related Questions