滚动RecyclerView在上方显示选定的项目

我正在寻找一种滚动RecyclerView来显示顶部的选定项目。

ListView我可以通过使用scrollTo(x,y)并获取需要居中的元素的顶部。

就像是:

 @Override public void onItemClick(View v, int pos){ mylistView.scrollTo(0, v.getTop()); } 

问题是RecyclerView在使用scrollTo方法时会返回一个错误

RecyclerView不支持滚动到绝对位置

我怎样才能滚动一个RecyclerView把选定的项目在视图的顶部?

如果你正在使用LinearLayoutManager或StaggeredGridLayoutManager,它们都有一个scrollToPositionWithOffset方法,该方法从RecyclerView的开始处取得位置和项目开始的偏移量,看起来好像它会完成你所需要的(设置偏移量到0应该与顶部alignment)。

例如:

 //Scroll item 2 to 20 pixels from the top linearLayoutManager.scrollToPositionWithOffset(2, 20); 

如果您正在寻找垂直LinearLayoutpipe理器,则可以使用自定义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); 将平滑滚动到回收站视图顶部的选定位置

//滚动项目位置

 linearLayoutManager.scrollToPositionWithOffset(pos, 0); 

你只需要调用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; } } } 

尝试什么对我很酷!

创build一个variablesprivate 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 /

刷新RecyclerView onbutton后,我做了什么来恢复滚动位置:

 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); 

在创buildlinearLayoutManager对象之前获取第一个可见项的偏移量,并在实例化LinearLayoutManager对象的scrollToPositionWithOffset之后调用该对象。

在特定位置滚动
这帮助了我很多。 通过点击监听器,你可以得到你的适配器的位置

 layoutmanager.scrollToPosition(int 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); 

似乎工作足够好,快速解决scheme。

在我的情况下,我的RecyclerView有这样的填充顶部

 <android.support.v7.widget.RecyclerView ... android:paddingTop="100dp" android:clipToPadding="false" /> 

然后为了滚动项目顶部,我需要

 recyclerViewLinearLayoutManager.scrollToPositionWithOffset(position, -yourRecyclerView.getPaddingTop());