如何给RecyclerView加上滚动条--现在就教你
时隔许久,我又要更博了,含蓄的话不多说了,今天我们的主题是这个RecyclerView。至于为什么要加个scrollBar?因为我的业务需求是需要一个实现成这样的,
效果图:(可能看起来比较粗糙,但功能实现了,你可以自定义修改嘛~哈哈哈)
可能我比较老派,我的app 中list的垂直布局还是喜欢用listView ,使用起来简单(可能博主我之前有个通用的adapter不舍得放弃吧,虽然RecyclerView也有通用的adapter,但总感觉显示简单的列表要多写几行代码,有点麻烦,哈哈哈,可能我就想偷懒吧)
但既然今天的是这个RecyclerView那么我们就开始详细的说明下吧~废话不多说切入正题。
注意:我这个View暂时只实现了垂直的View的ScrollBar的滚动,暂时没有横向实现,
未来可能我会拓展,敬请期待吧(大佬可能觉得太简单,勿喷,求教,谢谢)
先说下我的思路:
一、初始思路(想一个新玩意总得有个过程和弯路嘛),可能跟你想法一样哦
- 用一个LinearLayout 布局套住 RecyclerView 和一个自定义的View
- 自定义一个可以上下滚动的scrollBar
- 滚动的ScrollBar绑定RecyclerView的滚动事件
- Ok
二、现在的实现的思路 (我想了下如果用上面的方案实现的话就,必须写个xml文件,自定义一个ViewGroup,别人使用起来会很麻烦,当然你把他当成类库来用也很简单,而我就不想写xml)
- HobbyRecyclerView继承RecyclerView, 扩展这个功能
- 在HobbyRecyclerView 中先让子view的宽度缩小 ,留出给scrollBar的宽度
- 在HobbyRecyclerView中画一个ScrollBar ,这个bar的高度 = (view的可见高度 / view的所有子View的高度)* view可见高度 。
- 给HobbyRecyclerView加上滚动事件监听,监听滚动距离dy*(view的可见高度 / view的所有子View的高度)= scrollbar 的滚动距离
- 给scrollBar加上监听,监听拖动距离转化为 RecyclerView的滚动距离 = (scrollBar的拖动距离/scrollBar可滚动的区域高度(这里的区域高度等于View的高度)) * view的所有子View的高度
- 测试ok
思路也大概说了,那么就来看代码的实现吧。
/**
* @author mdm
* @Description HobbyRecyclerView
* @Version 1.0
*/
public class HobbyRecyclerView extends RecyclerView { private RectF mRangeRectf;
private Paint mRangPaint;
private int showMode = 1;
//滚动条宽高
private float scrollBarHeight;
private float scrollBarWidth;
//柱间隙
private float scrollWidthSpace ;
//滚动条宽度的等分比例
private int scrollWidthWeight = 10;
//Y轴的偏移值
private float yScrollOffset = 0;
//所有的子view的总高度 也就是这个
private float childViewAllHeight;
//可视区域的高度 其实这里就是View高度
private float visualHeight;
//可视区域的高度/所有的子view的总高度 得出的比例
float range;
//recyclerView的每个Item项的宽度
private int childWidth;
//判断触摸焦点
private boolean isFocus = false; //手触摸时点的x,y坐标
float x = 0;
float y = 0; public HobbyRecyclerView(@NonNull Context context) {
super(context);
}
public HobbyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
public HobbyRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context,attrs);
}
/**
* 初始化
* @param context
* @param attrs
*/
private void init(Context context, AttributeSet attrs) {
mRangeRectf = new RectF();
// region = new Region();
mRangPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mRangPaint.setStyle(Paint.Style.FILL);
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.HobbyRecyclerView);
showMode = ta.getInteger(R.styleable.HobbyRecyclerView_scrollBarMode,1);
ta.recycle();
addOnScrollListener(onScrollListener);
} @Override
protected void onMeasure(int widthSpec, int heightSpec) {
if(showMode != 1){
int width = MeasureSpec.getSize(widthSpec);
scrollBarWidth = width / scrollWidthWeight;//取10分之一
scrollWidthSpace = scrollBarWidth / 10; //获取间隙
childWidth = (int) (width - scrollBarWidth);
scrollBarWidth = scrollBarWidth - 2 * scrollWidthSpace;
for (int i = 0; i < getChildCount(); i++) {
measureChild(getChildAt(i),childWidth,heightSpec);
getChildAt(i).getLayoutParams().width = childWidth;
}
setMeasuredDimension(width,heightSpec);
}else {
super.onMeasure(widthSpec, heightSpec);
} }
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
visualHeight = getMeasuredHeight();
childViewAllHeight = getChildAt(2).getHeight() * getAdapter().getItemCount();
range = 0;
if(childViewAllHeight != 0){
range = visualHeight / childViewAllHeight;
}
scrollBarHeight = range * visualHeight;
} @Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
drawRange(canvas);
} private void drawRange(Canvas canvas){
if(canvas == null) return;
mRangeRectf.set(childWidth + scrollWidthSpace,yScrollOffset,childWidth + scrollBarWidth ,yScrollOffset + scrollBarHeight);
if(isFocus) {
mRangPaint.setColor(Color.parseColor("#2386BF"));
}else{
mRangPaint.setColor(Color.parseColor("#2EB3FF"));
}
canvas.drawRect(mRangeRectf,mRangPaint);
Log.i("tag" , "yScrollOffset ------- " + yScrollOffset);
Log.i("tag" , "scrollBarHeight ------- " + scrollBarHeight);
Log.i("tag" , "yScrollOffset ------- " + yScrollOffset);
} private RecyclerView.OnScrollListener onScrollListener = new 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);
yScrollOffset += dy * range;
}
};
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
//获取屏幕上点击的坐标
x = event.getX();
y = event.getY();
if(x >= mRangeRectf.left
&& x <= mRangeRectf.right
&& y >= mRangeRectf.top
&& y <= mRangeRectf.bottom){
isFocus = true;
invalidate();
}
break;
case MotionEvent.ACTION_MOVE:
if(x >= mRangeRectf.left
&& x <= mRangeRectf.right
&& y >= mRangeRectf.top
&& y <= mRangeRectf.bottom){
float diffValue = event.getY() - y;
scrollBy(0, (int) ((diffValue/visualHeight) * childViewAllHeight));
y = event.getY();
}
break;
case MotionEvent.ACTION_UP:
isFocus = false;
invalidate();
break;
}
if(x >= childWidth
&& x <= getMeasuredWidth()
&& y >= 0
&& y <= getMeasuredHeight()){
return true;
}else return super.onTouchEvent(event);
} /**
* //当前RcyclerView显示区域的高度。水平列表屏幕从左侧到右侧显示范围
int extent = this.computeHorizontalScrollExtent(); //整体的高度,注意是整体,包括在显示区域之外的。
int range = this.computeHorizontalScrollRange(); //已经向下滚动的距离,为0时表示已处于顶部。
int offset = this.computeHorizontalScrollOffset();
*/
}
是不是很简单呢?
ok有什么问题自己看吧。如果你看到最后几行注释了,那么你会疑问,那是因为我看了这个文章
仿拼多多可水平滚动RecyclerView,自定义滚动条滚动距离
如何给RecyclerView加上滚动条--现在就教你的更多相关文章
- CSS 页面顶部阴影和给浏览器强制加上滚动条
/*给浏览器强制加上滚动条*/ html{height: 101%;} /*页面顶部阴影*/ body:before{ content: ""; position: fixed; ...
- delphi Timage 加上滚动条方法
elphi Timage 加上滚动条方法 1:将 Timage 放入 TScrollBox内,即 [1]设image1.parent:= ScrollBox1; [2]在Object Ins ...
- Android开发15——给TextView加上滚动条
给TextView加上滚动条非常简单,只需要把TextView标签放在ScrollView标签中 <ScrollView android:layout_width="wrap_cont ...
- [Android Pro] 完美解决隐藏Listview和RecyclerView去掉滚动条和滑动到边界阴影的方案
reference to : http://blog.csdn.net/ming2316780/article/details/51578621 一.首先是Listview的属性设置 设置滑动到顶部和 ...
- 高分辨率下IE浏览器缩放导致出现右侧滚动条问题的解决
0 问题描述 由于需要演示触控操作,采购了SurfacePro,SurfacePro的推荐分辨率为2736×1824,且默认缩放比例为200%,IE浏览器的默认缩放比例也是200%,这样就导致右侧出现 ...
- 谷歌下设置滚动条的css样式
.oLi-lists-scroll::-webkit-scrollbar { width:5px; padding:1px; background:url(../images/repeat-bar. ...
- RecyclerView.ItemDecoration
decoration 英文意思: 英[ˌdekəˈreɪʃn] 美[ˌdɛkəˈreʃən] n. 装饰品; 装饰,装潢; 装饰图案,装饰风格; 奖章; [例句]The decoration and ...
- 在RecyclerView列表滚动的时候显示或者隐藏Toolbar
先看一下效果: 本文将讲解如何实现类似于Google+应用中,当列表滚动的时候,ToolBar(以及悬浮操作按钮)的显示与隐藏(向下滚动隐藏,向上滚动显示),这种效果在Material Design ...
- IE6下出现横向滚动条问题的解决方案
当我们在css样式设置为html {overflow-y:auto;}时,在ie7以上版本应用时不会有问题,可是在ie6下就会发现垂直滚动条出现会引起横向滚动条出现.究其原因是在ie6下,当内容过多出 ...
随机推荐
- 将本地jar包添加到maven中
将需要引入的jar包拷贝到maven项目的WEB-INF/lib中 在pom.xml中配置如下: <dependency> <groupId>com.xxxxx.union&l ...
- iOS 中 JSON 数据交换格式
JSON (JavaScript Object Notation)是一种轻量级的数据交换格式. JSON 的详细教程,能够參见 JSON 中国:http://www.json.org.cn/ ...
- .net framework中重新注册IIS
要为 ASP.NET 修复 IIS 映射,请按照下列步骤执行操作:运行 Aspnet_regiis.exe 实用工具:单击“开始”,然后单击“运行”.在“打开”文本框中,键入 cmd,然后按 ENTE ...
- sqlite developer注册码
sqlite developer注册码网上没有找到,只有通过注册表,删除继续使用,删除注册表中 HKEY_CURRENT_USER\SharpPlus\SqliteDev.
- SQLServer:探讨EXEC与sp_executesql的区别详解
摘要 MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的 ...
- jQuery Recipies - 使用map来过滤对应的元素集
<table id="tblEmployee" class="normal_table"> <tr> <td>Employe ...
- Android面试常问到的知识点
一.算法,数据结构 1.排序算法 2.查找算法 3.二叉树 4.广度,深度算法: 二.java基础 1.集合Collection,List,Map等常用方法,特点,关系: 2.线程的同步,中断方式有几 ...
- 《C++编程思想》(第二版)第3章 C++中的C(笔记、习题及答案)(二)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- .Net 程序员面试 C# 语言篇 (回答Scott Hanselman的问题)
过去几年都在忙着找项目,赶项目,没有时间好好整理深究自己在工作中学到的东西.现在好了,趁着找工作的这段空余时间,正好可以总结和再继续夯实自己的.Net, C#基本功.在05年的时候,Scott Han ...
- spring中aop以xml配置方式
1 引jar包 springAOP\aopalliance.jar springAOP\aspectjrt.jar springAOP\aspectjweaver.jar springAOP\spri ...