自定义RecyclerView的scrollbar
程序员文章站
2022-05-29 16:25:27
...
需求确定
在顶部RecyclerView的下面有一个蓝色的scrollbar,灰色区域代表整个RecyclerView,蓝色区域代表当前显示位置。
直接上代码
public class RecyclerViewSlidingBar extends View {
private Paint allPaint, inPaint;
private float mRoundRadius = 0;
private RectF mViewRect, mInRect;
private int viewWidth;
private int viewHeight;
private boolean canShow = false;
public RecyclerViewSlidingBar(Context context) {
this(context, null);
}
public RecyclerViewSlidingBar(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public RecyclerViewSlidingBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
allPaint = new Paint();
allPaint.setAntiAlias(true); // 抗锯齿
allPaint.setDither(true); // 防抖动
allPaint.setColor(Color.parseColor("#FFD4D7DD"));
allPaint.setStyle(Paint.Style.FILL);
inPaint = new Paint();
inPaint.setAntiAlias(true); // 抗锯齿
inPaint.setDither(true); // 防抖动
inPaint.setColor(Color.parseColor("#FF1DA1FF"));
inPaint.setStyle(Paint.Style.FILL);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
viewWidth = getWidth();
viewHeight = getHeight();
mViewRect = new RectF(0, 0, viewWidth, viewHeight);
mRoundRadius = viewHeight / 2;
}
@Override
protected void onDraw(Canvas canvas) {
if (canShow) {
canvas.drawRoundRect(mViewRect, mRoundRadius, mRoundRadius, allPaint);
canvas.drawRoundRect(mInRect, mRoundRadius, mRoundRadius, inPaint);
}
}
private float rvWidth;
private float rvViewWidth;
private float pointWidth;
private float scroll;
private float coefficient;
public void bindRecyclerView(final RecyclerView mRv) {
mRv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.e("onGlobalLayout", "onGlobalLayout");
rvWidth = mRv.computeHorizontalScrollRange();
rvViewWidth = mRv.getWidth();
canShow = rvWidth > rvViewWidth;
if (!canShow) return;
coefficient = viewWidth / rvWidth;
pointWidth = rvViewWidth / rvWidth * viewWidth;
mInRect = new RectF(0, 0, pointWidth, viewHeight);
invalidate();
mRv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
mRv.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.e("onScrolled", dx + ":" + rvWidth);
if (dx != 0) {
scroll = coefficient * dx;
mInRect.left += scroll;
mInRect.right += scroll;
invalidate();
}
}
});
}
});
}
}
使用
在RecyclerView设置数据后调用bindRecyclerView()方法。
拓展
需求有个地方是和这个RecyclerView有关的,8个以下的时候从上到下,从左到右配排序,超过8的时候多出item向右延伸,然后从上到下排,前8个不变。
if (mListAction.size() > 8) {
manager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.HORIZONTAL);
Collections.swap(mListAction, 1, 2);
Collections.swap(mListAction, 1, 4);
Collections.swap(mListAction, 3, 6);
Collections.swap(mListAction, 3, 5);
} else {
manager = new GridLayoutManager(getActivity(), 4);
}
我是这么做的,少于8个使用GridLayoutManager,实现前8个的排序方案,多于8个使用使用StaggeredGridLayoutManager,通过List位置交换,达到8个以上的排序方案。
上一篇: char判断字符串中是否含有某个字符
下一篇: 约瑟夫环图文详解
推荐阅读
-
Java Collections.sort()实现List排序的默认方法和自定义方法
-
yii2中的rules 自定义验证规则详解
-
Python自定义类的数组排序实现代码
-
Android中RecyclerView实现Item添加和删除的代码示例
-
Android 中自定义ContentProvider与ContentObserver的使用简单实例
-
springboot中使用自定义两级缓存的方法
-
android的RecyclerView实现拖拽排序和侧滑删除示例
-
解析C#自定义控件的制作与使用实例的详解
-
IOS 开发之PickerView自定义视图的实例详解
-
wordpress自定义标签云与随机获取标签的方法详解