Answers:
如果您使用LinearLayoutManager
或Staggered GridLayoutManager
,则它们每个都有一个scrollToPositionWithOffset方法,该方法同时获取位置以及项目开始位置相对于开始位置的偏移量RecyclerView
,这似乎可以满足您的需要(将偏移量设置为0应该与顶部对齐)。
例如:
//Scroll item 2 to 20 pixels from the top
linearLayoutManager.scrollToPositionWithOffset(2, 20);
如果您正在寻找垂直的LinearLayout Manager,则可以使用自定义实现平滑滚动LinearSmoothScroller
:
import android.content.Context;
import android.graphics.PointF;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;
public class SnappingLinearLayoutManager extends LinearLayoutManager {
public SnappingLinearLayoutManager(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 SnappingLinearLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
@Override
protected int getVerticalSnapPreference() {
return SNAP_TO_START;
}
}
}
在回收站视图中使用layoutmanager的一个实例,然后调用 recyclerView.smoothScrollToPosition(pos);
将平滑滚动到回收站视图顶部的选定位置
getHorizontalSnapPreference()
TopSnappedSmoothScroller中为“水平”列表重写。
RecyclerView
?这就是说:这似乎没有工作的最后一个项目-不管的SNAP_TO_START
的RecyclerView
唯一滚动,直到该项目在底部变得可见,但不动它一路攀升。关于如何实现这一目标的任何想法?(我已经通过在上设置自定义填充来解决此问题,RecyclerView
但这似乎并不正确...)
您只需要打电话recyclerview.scrollToPosition(position)
。没关系!
如果要在适配器中调用它,只需让适配器具有recyclerview实例或包含recyclerview的活动或片段,然后getRecyclerview()
在其中实现该方法即可。
希望对您有所帮助。
与调速器相同
public class SmoothScrollLinearLayoutManager extends LinearLayoutManager {
private static final float MILLISECONDS_PER_INCH = 110f;
private Context mContext;
public SmoothScrollLinearLayoutManager(Context context,int orientation, boolean reverseLayout) {
super(context,orientation,reverseLayout);
mContext = context;
}
@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
int position) {
RecyclerView.SmoothScroller smoothScroller = new TopSnappedSmoothScroller(recyclerView.getContext()){
//This controls the direction in which smoothScroll looks for your view
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return new PointF(0, 1);
}
//This returns the milliseconds it takes to scroll one pixel.
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
}
};
smoothScroller.setTargetPosition(position);
startSmoothScroll(smoothScroller);
}
private class TopSnappedSmoothScroller extends LinearSmoothScroller {
public TopSnappedSmoothScroller(Context context) {
super(context);
}
@Override
public PointF computeScrollVectorForPosition(int targetPosition) {
return SmoothScrollLinearLayoutManager.this
.computeScrollVectorForPosition(targetPosition);
}
@Override
protected int getVerticalSnapPreference() {
return SNAP_TO_START;
}
}
}
尝试对我有用的东西!
创建一个变量 private static int displayedposition = 0;
现在查看您的RecyclerView在“活动”中的位置。
myRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager llm = (LinearLayoutManager) myRecyclerView.getLayoutManager();
displayedposition = llm.findFirstVisibleItemPosition();
}
});
将此语句放在您希望将其显示在视图中的旧站点的位置。
LinearLayoutManager llm = (LinearLayoutManager) mRecyclerView.getLayoutManager();
llm.scrollToPositionWithOffset(displayedposition , youList.size());
就是这样,对我来说效果很好\ o /
只需简单地调用此方法:
((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(yourItemPosition,0);
代替:
recyclerView.scrollToPosition(yourItemPosition);
在刷新单击的RecyclerView后,我如何恢复滚动位置:
if (linearLayoutManager != null) {
index = linearLayoutManager.findFirstVisibleItemPosition();
View v = linearLayoutManager.getChildAt(0);
top = (v == null) ? 0 : (v.getTop() - linearLayoutManager.getPaddingTop());
Log.d("TAG", "visible position " + " " + index);
}
else{
index = 0;
}
linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.scrollToPositionWithOffset(index, top);
在创建linearLayoutManager对象之前和实例化之后,获取第一个可见项与顶部的偏移量,然后调用LinearLayoutManager对象的scrollToPositionWithOffset。
If you want to scroll automatic without show scroll motion then you need to write following code:
**=> mRecyclerView.getLayoutManager().scrollToPosition(position);**
If you want to display scroll motion then you need to add following code.
=>Step 1: You need to declare SmoothScroller.
RecyclerView.SmoothScroller smoothScroller = new
LinearSmoothScroller(this.getApplicationContext()) {
@Override
protected int getVerticalSnapPreference() {
return LinearSmoothScroller.SNAP_TO_START;
}
};
=>step 2: You need to add this code any event you want to perform scroll to specific position.
=>First you need to set target position to SmoothScroller.
**smoothScroller.setTargetPosition(position);**
=>Then you need to set SmoothScroller to LayoutManager.
**mRecyclerView.getLayoutManager().startSmoothScroll(smoothScroller);**
没有一个答案说明如何在顶部显示最后一个项目。因此,答案仅适用于在其上方或下方仍具有足够的项目以填充其余项目的项目RecyclerView
。例如,如果有59个元素并且选择了第56个元素,则它应位于顶部,如下图所示:
我们可以处理由使用的情况下linearLayoutManager.scrollToPositionWithOffset(pos, 0)
和一个额外的逻辑成Adapter
的RecyclerView
-通过增加的最后一项下方的自订利润率(如果最后一个项目是不可见的话,那就意味着有足够的空间填充的RecyclerView
)。自定义边距可以是根视图高度和项目高度之间的差异。因此,您的
Adapter
for RecyclerView
如下所示:
...
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
...
int bottomHeight = 0;
int itemHeight = holder.itemView.getMeasuredHeight();
// if it's the last item then add a bottom margin that is enough to bring it to the top
if (position == mDataSet.length - 1) {
bottomHeight = Math.max(0, mRootView.getMeasuredHeight() - itemHeight);
}
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)holder.itemView.getLayoutParams();
params.setMargins(0, 0, params.rightMargin, bottomHeight);
holder.itemView.setLayoutParams(params);
...
}
...
如果你LayoutManager
是LinearLayoutManager
,你使用scrollToPositionWithOffset(position,0);
它,它会让你的项目的第一个可见项目在列表中。否则,您可以smoothScrollToPosition
在RecyclerView
直接。
我最终使用了以下代码。
RecyclerView.LayoutManager layoutManager = mainList.getLayoutManager();
if (layoutManager instanceof LinearLayoutManager) {
// Scroll to item and make it the first visible item of the list.
((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(position, 0);
} else {
mainList.smoothScrollToPosition(position);
}
我使用下面的代码将一个项目(thisView)平滑滚动到顶部。
它也适用于具有不同高度的视图的GridLayoutManager:
View firstView = mRecyclerView.getChildAt(0);
int toY = firstView.getTop();
int firstPosition = mRecyclerView.getChildAdapterPosition(firstView);
View thisView = mRecyclerView.getChildAt(thisPosition - firstPosition);
int fromY = thisView.getTop();
mRecyclerView.smoothScrollBy(0, fromY - toY);
似乎可以很好地工作,可以快速解决。
thisPosition
?