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>