Android RecyclerView定位到指定的item并置顶
程序员文章站
2022-05-04 19:53:54
...
具体项目开发中,会有这样的需求:进入到一个列表(含RecyclerView)页面以后,定位到指定的一个item,并且将此item显示在顶部。
说到RecyclerView的item定位,我们优先想到的可能是以下2种方式:
scrollToPosition(int position);
smoothScrollToPosition(int position);
第一个方法scrollToPosition(position)是定位到指定item,是瞬间显示在页面上,用户可见的范围。位置不固定。
第二个方法与第一个不同的是平滑到你指定的item,而scrollToPosition是瞬间定位到指定位置。
这2个方法,虽都定位到指定的item,但是都没有将target item置顶展示。
此时,我们可以用到LinearSmoothScroller类,LinearSmoothScroller的作用是可以让RecyclerView指定的item滑动到页面可见的范围之内。
1.实现原理:重写LinearSmoothScroller的calculateSpeedPerPixel()方法,重新设置滑动的速度。
当新建LinearSmoothScroller对象时,已经计算好了滚动的速度,滚动速度和像素密度有关,MILLISECONDS_PER_PX 越大滚动越慢。
public class LinearTopSmoothScroller extends LinearSmoothScroller {
/**
* MILLISECONDS_PER_INCH 值越大滚动越慢
*/
private float MILLISECONDS_PER_INCH = 0.03f;
private final Context context;
/**
* @param context context
* @param needFast 是否需要快速滑动
*/
public LinearTopSmoothScroller(Context context, boolean needFast) {
super(context);
this.context = context;
if (needFast) {
setScrollFast();
} else {
setScrollSlowly();
}
}
@Override
protected int getVerticalSnapPreference() {
return SNAP_TO_START;
}
@Override
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
//return super.calculateSpeedPerPixel(displayMetrics);
setScrollSlowly();
return MILLISECONDS_PER_INCH / displayMetrics.density;
}
public void setScrollSlowly() {
//建议不同分辨率设备上的滑动速度相同
//0.3f可以根据不同自己的需求进行更改
MILLISECONDS_PER_INCH = context.getResources().getDisplayMetrics().density * 0.3f;
}
public void setScrollFast() {
MILLISECONDS_PER_INCH = context.getResources().getDisplayMetrics().density * 0.03f;
}
}
2.如何调用:
/**
* 指定item并置顶
*
* @param position item索引
*/
public void scrollItemToTop(int position) {
LinearTopSmoothScroller smoothScroller = new LinearTopSmoothScroller(mContext,false);
smoothScroller.setTargetPosition(position);
mLayoutManager.startSmoothScroll(smoothScroller);
}
具体到需求代码中:
// 渐渐上滑定位到评论区域,如果页面是网络请求的数据,则可以等页面展示结束再滑动。
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// position根据自己的需求传入即可
binding.baseRecyclerView.scrollItemToTop(position);
}
}, 200);