Android RecyclerView snapping to wrong position

1.3k Views Asked by At

I have a horizontal layout manager and RecylerView. From that I made a carousel by setting really high itemCount and starting in the middle. Then to achieve snapping I followed the guide at http://www.plattysoft.com/2015/06/16/snapping-items-on-a-horizontal-list/

Usually snapping works great but there are filters for the list (latest, most linked etc.) which when selected reload the list with new items.

If the list was scrolled in the positive direction (swiping from right to left) then after reloading everything is great. But if it was scrolled in the negative direction then after reloading it snaps to wrong location (the length of a padding).

I tried logging all the parameters which are used in calculation but they of seem to be the same so I'm lost as to what is causing this.

Activity looks like this:

private RecyclerView myList;
private List<myItem> emptyList;
private myAdapter myAdapter;
final LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false);
Integer allPixels;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myAdapter = new myAdapter(this, emptyList);
    myList.setAdapter(myAdapter);
    myList.setLayoutManager(layoutManager);
    myList.setHasFixedSize(true);
    myList.addOnScrollListener(new RecyclerView.OnScrollListener() {

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        synchronized (this) {
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                calculatePositionAndScroll(recyclerView);            
            }
        }

    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        allPixels += dx;
    }
});

// get latest items
new getItems().execute();
}

// async task
public class getItems extends AsyncTask<ContentValues, Void, List<myItem>> {

    protected void onPostExecute(List<myItem> result) {

        myAdapter = new myAdapter(getApplicationContext(), result);
        myList.swapAdapter(myAdapter, false);

        allPixels = 0;
        myList.scrollToPosition((100000 / 2));

        calculatePositionAndScroll(myList);

    }
}

private void calculatePositionAndScroll(RecyclerView recyclerView) {    
    int expectedPosition = Math.round((allPixels + padding - itemWidth) / itemWidth);

    scrollListToPosition(recyclerView, expectedPosition);

}

private void scrollListToPosition(RecyclerView recyclerView, int expectedPosition) {
    float targetScrollPos;

    targetScrollPos = (expectedPosition * itemWidth) + itemWidth - padding;

    float missingPx = targetScrollPos - allPixels;
    Log.e("VARS", "expectedPosition: "+expectedPosition+" | itemWidth: "+itemWidth+" | padding: "+padding+
            " | allPixels: "+allPixels+" | targetPos: "+targetScrollPos+" missingPx: "+missingPx);
    if (missingPx > 5 || missingPx < -5) {
        recyclerView.smoothScrollBy((int) missingPx, 0);
    }

}

Normally items should look like this:

but after scrolling left and reloading with new list if moves it like this:

0

There are 0 best solutions below