欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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