RecyclerView垂直滚动条V2.0版本,支持自定义,自动计算比例(持续更新)

本文介绍了一个RecyclerView垂直滚动条的2.0版本,支持自定义和自动计算比例,适用于数据增删后的比例调整。通过监听ViewTreeObserver和RecyclerView的滚动事件,动态计算并更新滚动条位置。源代码已提供,便于理解实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RecyclerView垂直滚动条V2.0版本,支持自定义,自动计算比例(持续更新)

又过去很久的时间啦,已经很久没有写过博客了,最近一年里又有了很多的收获,自学自定义View,View的事件处理等。今天在这里分享一下最近根据产品的要求制作的RecyclerView垂直滚动条简化自定义版本。该2.0版本基于原来的Rv自定义滚动条来实现的,并不是适合所有人,其中的算法是经过修改和改进,另外考虑到数据在删除和增加后距离发生变化时需要进一步重新修改比例。本文2.0仅仅以数据删除后距离缩短进行了矫正后续会出3.0版本对Rv自定义滚动条进行封装,敬请期待。

1.0版本链接
https://blog.youkuaiyun.com/hhw332704304/article/details/88971381?spm=1001.2014.3001.5501

废话不多说直接上代码

//设置全局变量
 private RecyclerView mSideslipRv;
 private View mScrollbar;
 private RelativeLayout mRlScrollbar;
 //记录每次滑动的距离
 float endY = 0;
 //记录当前Rv的总距离,包含屏幕外距离单位为Px
 int range = 0;
 //计算Rv屏幕外距离
 float maxEndY = 0.0f;
 //滑动滚动条的可移动的距离
 int transMaxRange = 0;
 //当前rv滑动的比例占总的可滑动距离的比例
 float proportion = 0.0f;
 //滚动条移动的距离
 float scrollY = 0.0f;


 mSideslipRv = view.findViewById(R.id.rv_sildes);
 mScrollbar = view.findViewById(R.id.view_scrollbar);
 mRlScrollbar = view.findViewById(R.id.rl_scrollbar);
 //监听ViewTreeObserve用于当删除数据执行数据刷新notifyDataSetChange后range发生变化可以在此监听中捕捉到
 mSideslipRv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
            	//获取当前Rv垂直方向总高度
                range = mSideslipRv.computeVerticalScrollRange();
                //计算Rv总高度减当前Rv可视区域高度,我的屏幕Rv当前可是高度是rv.getHeight所以是减去它,根据实际情况去计算
                maxEndY = range - mSideslipRv.getHeight();
                //计算滚动条的可滚动高度
                transMaxRange = ((ViewGroup) mScrollbar.getParent()).getHeight() - mScrollbar.getHeight();
                //滑动到顶部和底部进行矫正因小数或其他造成的误差
                if (!mSideslipRv.canScrollVertically(1)) {
                    endY = maxEndY;
                    scrollY = transMaxRange;
                } else if (!mSideslipRv.canScrollVertically(-1)) {
                    endY = 0;
                    scrollY = 0;
                }
                if (maxEndY > 0) {
                    mRlScrollbar.setVisibility(View.VISIBLE);
                    mScrollbar.setTranslationY(scrollY);
                } else {
                    mRlScrollbar.setVisibility(View.INVISIBLE);
                }
            }
        });

 mSideslipRv.addOnScrollListener(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);
                range = mSideslipRv.computeVerticalScrollRange();
                maxEndY = range - mSideslipRv.getHeight();
                endY += dy;
                //用于矫正endY因为小数相除不精准的问题
                if(!mSideslipRv.canScrollVertically(1)){
                    endY = maxEndY;
                }else if(!mSideslipRv.canScrollVertically(-1)){
                    endY = 0;
                }
                //计算滑动比例
                proportion = endY / maxEndY;
                transMaxRange = ((ViewGroup) mScrollbar.getParent()).getHeight() - mScrollbar.getHeight();
                scrollY = transMaxRange * proportion;
                if(maxEndY > 0) {
                    mRlScrollbar.setVisibility(View.VISIBLE);
                    mScrollbar.setTranslationY(scrollY);
                }else{
                    mRlScrollbar.setVisibility(View.INVISIBLE);
                }
            }

核心代码如上
不懂的可以看1.0版本
xml滚动条布局如下

 <RelativeLayout
 		android:layout_id="@+id/rl_scrollbar"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content">
			<View
				 android:layout_id="@+id/view_scrollbar"
				 android:layout_width="4dp"
				 android:layout_height="100dp"
				 android:background="@drawable/horizontal_track"/>
			<View
				 android:id="@+id/line"
				 android:layout_width="1dp"
				 android:layout_height="530dp"
				 android:background="#FF0000"
				 android:layout_toEndof="@+id/view_scrollbar"/>
 </RelativeLayout>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值