我找到了一个解决方案,它使用
scrollToPositionWithOffset
方法而不是使用
scrollBy
。即使两者都可以滚动到其他位置,但它们在后台的工作过程确实不同。
例如:如果您尝试使用
scrollBy
滚动到任何像素位置,并且您的recyclerView没有设置任何适配器,这意味着没有任何数据显示,因此还没有任何项目,则
scrollBy
将不起作用。RecyclerView使用其LayoutManager的
scrollBy
方法。因此,在我的情况下,我正在使用
LinearLayoutManager
来管理水平recyclerViews。
让我们看看它在做什么:
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;
}
正如您所看到的,如果此时没有任何子元素,
scrollBy
将忽略滚动意图。
if (getChildCount() == 0 || dy == 0) {
return 0;
}
另一方面,即使没有设置任何数据,
scrollToPosition
也可以完美地工作。根据
Pro RecyclerView slide,下面的示例能够完美地运行。但是使用scrollBy则不行。
void onCreate(SavedInstanceState state) {
....
mRecyclerView.scrollToPosition(selectedPosition);
mRecyclerView.setAdapter(myAdapter);
}
作为结果,我已经改变了一些东西来使用
scrollToPositionWithOffset()
。在这个实现之前,我正在计算精确的滚动x位置作为像素。之后,当滚动处于空闲状态时,将第一个完整可见位置计算为
scrollToPositionWithOffset()
的第一个参数。对于第二个参数,即偏移量,我使用
view.getLeft()
函数获取值,该函数有助于获取此视图相对于其父视图的左侧位置。
![enter image description here](https://istack.dev59.com/gZvMT.gif)
它完美地运行了!!