sephiroth74/HorizontalVariableListView

Disapearing items, when scrolling HVLV

Closed this issue · 5 comments

What should I do to use HorizontalVariableListView with BaseAdapter. I have class:

public class BrochuresHorizontalAdapter extends BaseAdapter{
private SparseArray items;
...
}
which stores list items in SparseArray. Unfortunately sometimes removed views by recycler are not recreated. getView is not invoked on low positions and items simply disappear. (--update: getView() is invoked)

Is it because I need some special things to make it work as Listview?

maybe question doesn't have sense, because BaseAdapter implements ListAdapter. But what could cause such behavior.

does it change something if you use a default ArrayAdapter?

Also maybe it's caused partially by fact that each view is different in my list:

@Override
public int getItemViewType(int position) {
    return position;
}

@Override
public int getViewTypeCount() {
                       items.size()+1;
}

Not always it's easy to reproduce error, usually very fast scrolling causes that. And of course only on older device with 50MB memory and many small images in the list.

notifyDataSetChanged() fixes lacking items, but it's not a solution.

I read more about adapters, and ArrayAdapter is not proper when you want to show more complicated views with images and not just text. Anyway I read source of ArrayAdapter, and I don't think that using BaseAdapter could cause items to disappear.

I've started debugging the code. I see that when I have for example 25 items, I scroll to the last one and then back to the first one, following happens:

  • last visible item is 9th
  • getView() for view number 8 is invoked (but it's not shown), i cannot scroll more left
  • this getView() has proper view and returns it.

in HorizontalVariableListView class, commenting out removeNonVisibleItems( mCurrentX ); fixes problem. But I guess that then views recycler stops working... The problem occurs always on phones with low memory. In new Nexus 10 it has never happened. Sometimes all items disappear. It doesn't happen when items don't have many icons inside.

@Override
public void trackMotionScroll( int newX ) {

    scrollTo( newX, 0 );
    mCurrentX = getScrollX();
//  removeNonVisibleItems( mCurrentX );

    fillList( mCurrentX );
    invalidate();
}

I will try to continue debuging on monday

Further code investigation led me to conclusion that conditions for removing not visible items are incorrect:

( child != null && child.getRight() - positionX <= mLeftEdge )
and
( child != null && child.getLeft() - positionX >= mRightEdge )

They're sometimes removing visible items. When I comment out removing items from the left side then they're not disappearing any more. But if I understand code correctly, that turns off recycler for right scrolling.

private void removeNonVisibleItems( final int positionX ) {
    View child = getChildAt( 0 );


    // remove to left...
    //while ( child != null && child.getRight() - positionX <= mLeftEdge ) {
    //
    //  if ( null != mAdapter ) {
    //      int position = getPositionForView( child );
    //      int viewType = mAdapter.getItemViewType( position );
    //      mRecycleBin.get( viewType ).offer( child );
    //  }
    //  removeViewInLayout( child );
    //  mLeftViewIndex++;
    //  child = getChildAt( 0 );
    //}

    // remove to right...
    child = getChildAt( getChildCount() - 1 );
    while ( child != null && child.getLeft() - positionX >= mRightEdge ) {

        if ( null != mAdapter ) {
            int position = getPositionForView( child );
            int viewType = mAdapter.getItemViewType( position );
            mRecycleBin.get( viewType ).offer( child );
        }

        removeViewInLayout( child );
        mRightViewIndex--;
        child = getChildAt( getChildCount() - 1 );
    }   
}

Author help would be appreciated.

No such error in new version:
Malachiasz@dc50eee