RecyclerView使用技巧-自动滚动

今天跟大家分享下RecyclerView怎么使它的条目自动滚动


其实做这个也是项目中有个需求需要用到,但是在网上找遍了也没有找到专门讲解这个知识点的文章。
所以这段时间自己研究懂了后 分享给大家。

再次更新下,找到了一个新的解决办法,那就是 RecyclerView 的smoothScrollToPosition方法。其实这个方法之前用过,也是可以平滑滚动,但是速度太快,没办法自定义时间。所以就没有说 ,但是昨天晚上经过简友的提醒,我又细心的找了一遍,发现这个方法确实是可以改变时间的 而且不用像下面那么麻烦而且解决了所有问题,简直棒到没朋友,那么下面是解决方法。
[RecyclerView调用smoothScrollToPosition() 控制滑动速度]


一想到条目自动滚动,让我想起了ListView有一个方法叫做setSelection(int position) 可以设置一个位置 然后他就会自动滚动到指定的位置,但是现在这都什么年代了 果断抛弃了LisView 使用RecyclerView来做 至于RecyclerView有什么好处 为什么使用它 大家自行Google吧。

那么我们回到RecyclerView中想想该怎么实现这个呢 找了找RecyclerView中方法 发现有这么一个方法scrollToPosition(int position)这个方法跟ListView的一样也是传入进去一位置 自动给你跳到指定的位置 ,这会儿 你可能心想 我去这不是直接就实现了么,但是 你用下看效果 那个条目跟瞬移是的 直接就干到最底部了! (如果你们产品能接受 那就当我没说) 既然这样不行 那就换,突然想到谷歌给我们提供了一个叫做Scroller的类 看描述!

Scroller是一个专门用于处理滚动效果的工具类,可能在大多数情况下,我们直接使用Scroller的场景并不多,但是很多大家所熟知的控件在内部都是使用Scroller来实现的,如ViewPager、ListView等。

不熟悉的可以看下这篇博客[Android Scroller完全解析,关于Scroller你所需知道的一切]


其实说到底他也就还是个工具类 也就是说其实最后能让Item滚动并不是他 这时候就要介绍下我们的另外两个方法 scrollTo()和scrollBy()这两个方法 这两个才是主角 就是这个两个方法才能让我们的View滑动 他们的使用也很简单 就是传入 一个x坐标 和一个 y坐标 他就会照着你给的位置去移动 他俩不一样的地方无非就是 scrollTo 是以当前View的初始位置开始移动 而scrollBy是根据当前位置来进行移动 而其他的特性大家也可以看上面的博客 这里就不絮叨了,

那么大家知道scrollTo()和scrollBy()的移动方式 就是移动他的内容 而不是他自己本身,那这里正好 我们不就是想移动RecyclerView的Item么?但是用过你会发现,我去,这家伙怎么跟之前用的那个设置位置移动的方法一个德行 ,也嗖的一下就干过去了 .不过他并不是移动到底 如果是上下滑动的话 是根据你的y值而决定的 。

那么下面就要用到Scroller这个类了
使用startScroll(int startX, int startY, int dx, int dy)开始启动滑动 并且重写computeScroll()方法完成值得过度 并且调用invalidate();方法请求View数重新绘制 这个一定要记得调用 不要会没有效果

@Override public void computeScroll() { //重写computeScroll()方法,并在其内部完成平滑滚动的逻辑 if (mScroller.computeScrollOffset()) { scrollBy(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } }
看下效果

GIF.gif

使用后你会发现,哎确实是自动滚动了,而且也不是嗖的一下在就没了。 好像这样确实是已经实现了,但是如果我想让他滚动的在慢一点怎么办?或者说我想他的滚动速度是可以调的,那怎么办 ? 其实这个startScroll 还有一个重载的方法 startScroll(int startX, int startY, int dx, int dy, int duration) 可以再添加一个时间,单位是毫秒。

但是这里还有一个问题就是RecyclerView是不让使用scrollTo方法 如果使用了是没有效果的 而且还会打Log提醒

  RecyclerView does not support scrolling to an absolute position "Use scrollToPosition instead

第二种方法

到现在就已经是实现RecyclerView 的自动滚动效果了,但是有没有其他方法可以实现呢?当然有 ,那就是使用属性动画来实现。

属性动画我们大家都知道,分为两种重要的类,分别为ValueAnimator 和 ObjectAnimator,ValueAnimator 就是来计算我们给的初始值和结束值说白了就是对值进行计算来完成数值之间的过度动画 ,而ObjectAnimator不仅会对值进行计算还会通过反射的方式把计算出来的值赋值给做动画对象的属性,这里我只是说个大概,但是你有没有发现其实之前的Scroller也是我们给个开始位置 和结束为止 他来给我们计算数值 然后我们在scrollBy过去 你会发现这个计算值的过程跟上面的ValueAnimator 是不是老像了? 好 那我们就来试试 看看行不行。

//默认从0-200 valueAnimator = ValueAnimator.ofInt(200); valueAnimator.setDuration(5000); valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override publicvoidonAnimationUpdate(ValueAnimatoranimation) { //获取估值器给我们的返回值 int animatedValue = (int) animation.getAnimatedValue(); //调用RecyclerView的scrollBy执行滑动 recyclerView.scrollBy(0, animatedValue); Log.e("TAG", "animatedValue:" + animatedValue); } } ); valueAnimator.start();

你会发现效果是一样一样的 ,但是实验到这里 我想悲哀的告诉大家,这里面有个Bug,细心的可能发现了,当我们不论是用上面那种方法,当你的Item内容比较少,而我们的结束值又是随便设置的,执行时间稍微长一点 你就会发现,哎?我怎么不能往上面滑动了,但等一会又可以滑动了,其实是这个scrollBy还没有执行完, 还在往下滑动,只不过是滑动到头了,你看不见罢了 ,那又怎么决解这个问题呢 ?其实RecyclerView有一个监听 addOnScrollListener 如果你没有这个方法 说明你该更新了RecyclerView了 这个监听有两个回掉。

  1. onScrollStateChanged 滑动状态 两个参数一个View 一个状态 分为按下滑动 和抬起 和MotionEvent 是一样的 。
  2. onScrolled 三个参数 View 和 x,y轴滑动的量。

其实通过这两个回掉很简单的就能解决这个问题 就是我们只要能判断出当前这个RecyclerView 是不是滑动到底部就行了 在onScrollStateChanged中判断? 当滑动的状态为抬起的时候我们判断 不行 因为我们是使用scrollBy方法进行的滑动 妹的 这个方法根本就不会执行 他只有你手指滑动的时候才会执行,那咋办 只有在onScrolled 中判断了 这个方法才不会管你什么滑动呢 只要我动了 他就执行 那怎判断呢?
(直接图片了 代码这个格式真心没弄好 怎么弄都不行 !)

Paste_Image.png
Paste_Image.png
Paste_Image.png

大概的过程就是 ,我开始执行动画 ,然后不断判断是否达到最底部 ,不是得话就继续执行滑动。这时候呢,因为我监听了RecyclerVIew的滑动 一滑动我就判断。
怎么判断呢?得到当前显示的最后一个item的view,通过这个View 得到他的bottom坐标值,然后在获得RecyclerView的bottom坐标值,在拿到最后View的position,在拿到RecyclerView item的总数-1,他们四个进行比较。 都满足了,就能说明,当前已经滑动到最底部了,这时候给isBottom赋值为True ,接着动画监听里面我们之前不是做了判断么!满足else条件 取消动画,就不会在执行了,那个Bug也就解决了。
  但是现在这个方法还有效率问题,滑动就执行判断,而且还是获取View的各种信息,想办法在优化吧。还有一个就是,如果我们能知道具体移动到什么位置就好了 ,我们上面设置的是200,因为这个参数是坐标,而RecyclerView的内容其实已经超过屏幕坐标系了,这个问题待解决。。。。

好了 以上就是我总结的一些开发中的经验 如果有谁能知道解决这个办法 和写的不对的地方 欢迎指教 。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,312评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,578评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,337评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,134评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,161评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,303评论 1 280
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,761评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,421评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,609评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,450评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,504评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,194评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,760评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,836评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,066评论 1 257
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,612评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,178评论 2 341

推荐阅读更多精彩内容