在RecyclerView上,我可以使用以下命令突然滚动到所选项目的顶部:
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(position, 0);
但是,这突然将项目移动到顶部位置。我想顺利地移动到项目的顶部。
我也尝试过:
recyclerView.smoothScrollToPosition(position);
但它不能很好地工作,因为它不会将项目移动到选定的顶部位置。它只是滚动列表,直到位置上的项目可见。
RecyclerView
被设计为可扩展的,因此不需要为了执行滚动而将LayoutManager
(如droidev suggested)子类化。
相反,只需使用首选项SmoothScroller
创建一个SNAP_TO_START
:
RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(context) {
@Override protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}
};
现在,您可以设置要滚动到的位置:
smoothScroller.setTargetPosition(position);
并将SmoothScroller传递给LayoutManager:
layoutManager.startSmoothScroll(smoothScroller);
为此,您必须创建自定义LayoutManager
public class LinearLayoutManagerWithSmoothScroller extends LinearLayoutManager {
public LinearLayoutManagerWithSmoothScroller(Context context) {
super(context, VERTICAL, false);
}
public LinearLayoutManagerWithSmoothScroller(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
int position) {
RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext());
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
private class TopSnappedSmoothScroller extends LinearSmoothScroller {
public TopSnappedSmoothScroller(Context context) {
super(context);
}
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return LinearLayoutManagerWithSmoothScroller.this
.computeScrollVectorForPosition(targetPosition);
}
@Override
protected int getVerticalSnapPreference() {
return SNAP_TO_START;
}
}
}
将它用于RecyclerView并调用smoothScrollToPosition。
例如:
recyclerView.setLayoutManager(new LinearLayoutManagerWithSmoothScroller(context));
recyclerView.smoothScrollToPosition(position);
这将滚动到指定位置的RecyclerView项目的顶部。
希望这可以帮助。
我们可以这样试试
recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView,new RecyclerView.State(), recyclerView.getAdapter().getItemCount());
这是我在Kotlin写的一个扩展函数,直接在RecyclerView上调用(基于@Paul Woitaschek答案):
fun RecyclerView.smoothSnapToPosition(position: Int, snapMode: Int = LinearSmoothScroller.SNAP_TO_START) {
val smoothScroller = object: LinearSmoothScroller(this.context) {
override fun getVerticalSnapPreference(): Int {
return snapMode
}
override fun getHorizontalSnapPreference(): Int {
return snapMode
}
}
smoothScroller.targetPosition = position
layoutManager?.startSmoothScroll(smoothScroller)
}
像这样使用它:
myRecyclerView.smoothSnapToPosition(itemPosition)
我发现滚动RecyclerView
最简单的方法如下:
// Define the Index we wish to scroll to.
final int lIndex = 0;
// Assign the RecyclerView's LayoutManager.
this.getRecyclerView().setLayoutManager(this.getLinearLayoutManager());
// Scroll the RecyclerView to the Index.
this.getLinearLayoutManager().smoothScrollToPosition(this.getRecyclerView(), new RecyclerView.State(), lIndex);
覆盖LinearSmoothScroller中的calculateDyToMakeVisible / calculateDxToMakeVisible函数以实现偏移Y / X位置
override fun calculateDyToMakeVisible(view: View, snapPreference: Int): Int {
return super.calculateDyToMakeVisible(view, snapPreference) - ConvertUtils.dp2px(10f)
}
我喜欢这样:
recyclerView.getLayoutManager().smoothScrollToPosition(recyclerView, new RecyclerView.State(), 5);
可能@droidev方法是正确的,但我只想发布一些不同的东西,它基本上做同样的工作,不需要扩展LayoutManager。
这里有一个注意事项 - 如果你的项目(你要在列表顶部滚动的项目)在屏幕上可见,你只需要自动滚动到顶部就可以了。当列表中的最后一项具有某些操作时会很有用,这会在同一列表中添加新项目,并且您希望将用户集中在新添加的项目上:
int recyclerViewTop = recyclerView.getTop();
int positionTop = recyclerView.findViewHolderForAdapterPosition(positionToScroll) != null ? recyclerView.findViewHolderForAdapterPosition(positionToScroll).itemView.getTop() : 200;
final int calcOffset = positionTop - recyclerViewTop;
//then the actual scroll is gonna happen with (x offset = 0) and (y offset = calcOffset)
recyclerView.scrollBy(0, offset);
这个想法很简单:1。我们需要获得recyclerview元素的顶部坐标; 2.我们需要获取要滚动到顶部的视图项的顶部坐标; 3.最后我们需要做计算的偏移量
recyclerView.scrollBy(0, offset);
200只是示例硬编码整数值,如果视图所有者项不存在,您可以使用它,因为这也是可能的。