I have a vertically scrolling RecyclerView
with horizontally scrolling inner RecyclerViews just like this.
With this implementation, users can scro
I found a solution that is use scrollToPositionWithOffset
method instead using scrollBy
. Even if both of two scroll another position, they have really different work process in back side.
For example: if you try to use scrollBy
to scroll any pixel position and your recyclerView had not been set any adapter which means there is no any data to display and so it has no any items yet, then scrollBy
doesn't work. RecyclerView uses its layoutManager's scrollBy
method. So in my case, I am using LinearLayoutManager
to the horizontal recyclerViews.
Lets see what it's doing :
int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getChildCount() == 0 || dy == 0) {
return 0;
}
mLayoutState.mRecycle = true;
ensureLayoutState();
final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START;
final int absDy = Math.abs(dy);
updateLayoutState(layoutDirection, absDy, true, state);
final int consumed = mLayoutState.mScrollingOffset
+ fill(recycler, mLayoutState, state, false);
if (consumed < 0) {
if (DEBUG) {
Log.d(TAG, "Don't have any more elements to scroll");
}
return 0;
}
final int scrolled = absDy > consumed ? layoutDirection * consumed : dy;
mOrientationHelper.offsetChildren(-scrolled);
if (DEBUG) {
Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled);
}
mLayoutState.mLastScrollDelta = scrolled;
return scrolled;
}
As you can see scrollBy
ignores the scroll intentions if there is no any child at that time.
if (getChildCount() == 0 || dy == 0) {
return 0;
}
On the other hand scrollToPosition
can work perfectly even if there is no any set data yet.
According to the Pro RecyclerView slide, the below sample works perfectly. However you can not do that with scrollBy.
void onCreate(SavedInstanceState state) {
....
mRecyclerView.scrollToPosition(selectedPosition);
mRecyclerView.setAdapter(myAdapter);
}
As a result, I have changed little thing to use scrollToPositionWithOffset()
.
Before this implementation I was calculating the exact scroll x position as a pixel.
After that, when the scroll came idle state, calculating the first complete visible position to the first parameter of the scrollToPositionWithOffset()
.
For second parameter which is the offset, I am getting the value using view.getLeft()
function which helps to get left position of this view relative to its parent.
And it works perfectly!!