Android RecyclerView定位到指定的item并置顶

具体项目开发中,会有这样的需求:进入到一个列表(含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);

你可能感兴趣的:(Android,UI,Android动画,android,RecyclerView,RecyclerView滚动,安卓,Android)