EndlessAdapter with ListView header

1,060 views
Skip to first unread message

Phil

unread,
Apr 14, 2011, 6:26:06 PM4/14/11
to cw-android
I have been experimenting with the EndlessAdapter component and I'm
experiencing an issue when adding a header view to the ListView via
addHeaderView().

If the ListView has a header view, and I continue scrolling down until
the last "pending" row appears (i.e. this is the last page it will
load) I sometimes get the following exception thrown:

W/dalvikvm(12081): threadid=1: thread exiting with uncaught exception
(group=0x4001d7d0)
E/AndroidRuntime(12081): FATAL EXCEPTION: main
E/AndroidRuntime(12081): java.lang.IndexOutOfBoundsException: Invalid
index 0, size is 0
E/AndroidRuntime(12081): at
java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:257)
E/AndroidRuntime(12081): at java.util.ArrayList.get(ArrayList.java:
311)
E/AndroidRuntime(12081): at
android.widget.HeaderViewListAdapter.isEnabled(HeaderViewListAdapter.java:
164)
E/AndroidRuntime(12081): at
android.widget.ListView.dispatchDrawWithExcessScroll_Default(ListView.java:
3304)
E/AndroidRuntime(12081): at
android.widget.ListView.dispatchDraw(ListView.java:3045)
E/AndroidRuntime(12081): at android.view.View.draw(View.java:6800)
E/AndroidRuntime(12081): at
android.widget.AbsListView.draw(AbsListView.java:2628)
E/AndroidRuntime(12081): at
android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime(12081): at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime(12081): at android.view.View.draw(View.java:6800)
E/AndroidRuntime(12081): at
android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime(12081): at
android.view.ViewGroup.drawChild(ViewGroup.java:1640)
E/AndroidRuntime(12081): at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime(12081): at
android.view.ViewGroup.drawChild(ViewGroup.java:1638)
E/AndroidRuntime(12081): at
android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
E/AndroidRuntime(12081): at android.view.View.draw(View.java:6800)
E/AndroidRuntime(12081): at
android.widget.FrameLayout.draw(FrameLayout.java:352)
E/AndroidRuntime(12081): at
com.android.internal.policy.impl.PhoneWindow
$DecorView.draw(PhoneWindow.java:1894)
E/AndroidRuntime(12081): at android.view.ViewRoot.draw(ViewRoot.java:
1407)
E/AndroidRuntime(12081): at
android.view.ViewRoot.performTraversals(ViewRoot.java:1163)
E/AndroidRuntime(12081): at
android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
E/AndroidRuntime(12081): at
android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(12081): at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(12081): at
android.app.ActivityThread.main(ActivityThread.java:4627)
E/AndroidRuntime(12081): at
java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(12081): at
java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(12081): at com.android.internal.os.ZygoteInit
$MethodAndArgsCaller.run(ZygoteInit.java:858)
E/AndroidRuntime(12081): at
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
E/AndroidRuntime(12081): at dalvik.system.NativeStart.main(Native
Method)

I noticed that if I scroll slowly, this error can be avoided, but if I
scroll rapidly through the last pending row it will cause this
exception.

I am able to reproduce this in the EndlessAdapter demo code
(EndlessAdapterDemo.java) by calling addHeaderView to the ListView
before setting the adapter:

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);

ArrayList<Integer> items=new ArrayList<Integer>();

for (int i=0;i<25;i++) { items.add(i); }

getListView().addHeaderView(new View(this));
setListAdapter(new DemoAdapter(items));
}

Any thoughts on what I can do to alleviate this?

Thanks!
Phil

Mark Murphy

unread,
Apr 14, 2011, 6:34:58 PM4/14/11
to cw-an...@googlegroups.com
On Thu, Apr 14, 2011 at 6:26 PM, Phil <pols...@gmail.com> wrote:
> I have been experimenting with the EndlessAdapter component and I'm
> experiencing an issue when adding a header view to the ListView via
> addHeaderView().
>
> If the ListView has a header view, and I continue scrolling down until
> the last "pending" row appears (i.e. this is the last page it will
> load) I sometimes get the following exception thrown:

Yeah, that's not surprising.

> I noticed that if I scroll slowly, this error can be avoided, but if I
> scroll rapidly through the last pending row it will cause this
> exception.

Really? I would have expected it to fail all of the time.

> I am able to reproduce this in the EndlessAdapter demo code
> (EndlessAdapterDemo.java) by calling addHeaderView to the ListView
> before setting the adapter:
>
>        @Override
>        public void onCreate(Bundle icicle) {
>                super.onCreate(icicle);
>                setContentView(R.layout.main);
>
>                ArrayList<Integer> items=new ArrayList<Integer>();
>
>                for (int i=0;i<25;i++) { items.add(i); }
>
>                getListView().addHeaderView(new View(this));
>                setListAdapter(new DemoAdapter(items));
>        }
>
> Any thoughts on what I can do to alleviate this?

EndlessAdapter has a built-in assumption that it is the top-level
adapter. However, when you call addHeaderView() or addFooterView(),
Android creates its own decorating adapter, wrapped around
EndlessAdapter, and installs its adapter as the top level.

You can try an EndlessAdapter around a MergeAdapter
(https://github.com/commonsguy/cwac-merge) to see if that will give
you your header. I have this sneaking suspicion that this combination
will introduce its own set of problems, but it's at least worth
considering.

--
Mark Murphy (a Commons Guy)
http://commonsware.com | http://github.com/commonsguy
http://commonsware.com/blog | http://twitter.com/commonsguy

Android Training in NYC: http://marakana.com/training/android/

Phil

unread,
Apr 14, 2011, 7:19:06 PM4/14/11
to cw-android
> EndlessAdapter has a built-in assumption that it is the top-level
> adapter. However, when you call addHeaderView() or addFooterView(),
> Android creates its own decorating adapter, wrapped around
> EndlessAdapter, and installs its adapter as the top level.

Ah, that makes sense. Thanks for the quick response! I think I might
just try implementing my own addHeaderView() at the adapter level
instead.
Reply all
Reply to author
Forward
0 new messages