我希望我的RecyclerView与LinearLayoutManager在适配器更新后显示在特定项目的滚动位置。(不是第一个/最后一个位置)意味着第一次(重新)布局,这个给定的位置应该在可见区域。它不应该在顶部布局位置0,然后滚动到目标位置。
我的适配器从itemCount=0开始,在线程中加载其数据并稍后通知其真实计数。但是必须在计数仍然为0时已经设置了开始位置!
到目前为止,我使用了某种post Runnable
包含scrollToPopse
,但这有副作用(从第一个pos开始并立即跳转到目标位置(0-
编辑:为了澄清:我需要layoutManager. setStackFromEnd(true)的替代方案;
,类似于setStackFrom(位置)
。ScrollToPopse不起作用,如果我在itemCount仍然为0时调用它,那么它会被忽略。如果我在通知itemCount现在是时调用它
我自己找到了解决办法:
我扩展了LayoutManager:
class MyLayoutManager extends LinearLayoutManager {
private int mPendingTargetPos = -1;
private int mPendingPosOffset = -1;
@Override
public void onLayoutChildren(Recycler recycler, State state) {
if (mPendingTargetPos != -1 && state.getItemCount() > 0) {
/*
Data is present now, we can set the real scroll position
*/
scrollToPositionWithOffset(mPendingTargetPos, mPendingPosOffset);
mPendingTargetPos = -1;
mPendingPosOffset = -1;
}
super.onLayoutChildren(recycler, state);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
/*
May be needed depending on your implementation.
Ignore target start position if InstanceState is available (page existed before already, keep position that user scrolled to)
*/
mPendingTargetPos = -1;
mPendingPosOffset = -1;
super.onRestoreInstanceState(state);
}
/**
* Sets a start position that will be used <b>as soon as data is available</b>.
* May be used if your Adapter starts with itemCount=0 (async data loading) but you need to
* set the start position already at this time. As soon as itemCount > 0,
* it will set the scrollPosition, so that given itemPosition is visible.
* @param position
* @param offset
*/
public void setTargetStartPos(int position, int offset) {
mPendingTargetPos = position;
mPendingPosOffset = offset;
}
}
它存储我的目标位置。如果onLayout儿童
被RecyclerView调用,它会检查适配器itemCount是否已经
所以我可以立即告诉什么位置应该是可见的,但是在适配器中存在位置之前不会告诉LayoutManager。
你可以试试这个,它会滚动到你想要的位置:
rv.getLayoutManager().scrollToPosition(positionInTheAdapter).
如果您想滚动到特定位置并且该位置是适配器的位置,那么您可以使用StaggeredGridLayoutManager
scrollToPopse
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
staggeredGridLayoutManager.scrollToPosition(10);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
如果我理解这个问题,你想滚动到一个特定的位置,但该位置是适配器的位置,而不是回收器视图的项目位置。
您只能通过LayoutManager
来实现这一点。
rv.getLayoutManager().scrollToPosition(youPositionInTheAdapter);