You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've tried using your code but it severely lags when using a custom adapter. Looping through every view in computeScrollY() and inflating tons of views seems terribly inefficient and I have no clue how this code could work.
Am I missing something or have you tested this on any other adapter?
@egfconnor I think the issue relates to the fixed adapter size shown in the example. If you change the dataset (grow or shrink) in the adapter and then call notifyDataSetChanged on the adapter, an IndexOutOfBoundsException is thrown.
This is caused by the way @LarsWerkman defined the mItemOffsetY array in the computeScrollY function. As currently defined, the mItemOffestY array is defined ONLY once and the size is based on the initial size of the dataset.
To fix it so that it can accept changes in the dataset, change this line:
if (mItemOffsetY == null)
to
if (mItemOffsetY == null || mItemOffsetY.length != mItemCount)
That will allow the mItemOffsetY array to be redefined when the dataset changes and should allow it to work with custom adapters (especially cursoradapters and loaders).
Thanks for the info @bkhall. I will try and test this soon as currently I have went away from using it completely. Will hopefully create a sample that isolates everything to a simple level.
This is why I think this is not a good starting point in terms of breaking lots of conecpts crucial to ListViews and Adapters.
First: it breaks when adapter's content changes. Normally this is all well designed, a call to notifyDataSetChanged from the adapter informs all observers (the list). But this approach breaks this.
Second: in terms of efficiency it is a horrible mistake to call getView in a loop on ALL elements in the list. Never, ever, I repeat, never, ever, do this!
Activity
egfconnor commentedon Aug 28, 2013
Setting a boolean so it runs once has fixed it, but I'm not sure what the side effects are:
listView.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
boolean haveRan = false;
bkhall commentedon Sep 19, 2013
@egfconnor I think the issue relates to the fixed adapter size shown in the example. If you change the dataset (grow or shrink) in the adapter and then call notifyDataSetChanged on the adapter, an IndexOutOfBoundsException is thrown.
This is caused by the way @LarsWerkman defined the mItemOffsetY array in the computeScrollY function. As currently defined, the mItemOffestY array is defined ONLY once and the size is based on the initial size of the dataset.
To fix it so that it can accept changes in the dataset, change this line:
if (mItemOffsetY == null)
to
if (mItemOffsetY == null || mItemOffsetY.length != mItemCount)
That will allow the mItemOffsetY array to be redefined when the dataset changes and should allow it to work with custom adapters (especially cursoradapters and loaders).
egfconnor commentedon Sep 19, 2013
Thanks for the info @bkhall. I will try and test this soon as currently I have went away from using it completely. Will hopefully create a sample that isolates everything to a simple level.
LarsWerkman commentedon Sep 24, 2013
Thanks @bkhall yeah you could do that I think!
Zordid commentedon Mar 27, 2014
This is why I think this is not a good starting point in terms of breaking lots of conecpts crucial to ListViews and Adapters.
First: it breaks when adapter's content changes. Normally this is all well designed, a call to notifyDataSetChanged from the adapter informs all observers (the list). But this approach breaks this.
Second: in terms of efficiency it is a horrible mistake to call getView in a loop on ALL elements in the list. Never, ever, I repeat, never, ever, do this!
AlexeyFreelancer commentedon May 29, 2014
@Zordid do you have another solution for implementation? Could you to share it?