解决 RecyclerView AppBarLayout 滑动

作者: lguipeng | 来源:发表于2016-06-12 17:55 被阅读7059次

问题

如果你又看过 cheesesquare 这个项目就知道,在详情页滑动的时候有一些粘性,体验不是很好。
有人在YouTube上上传了现象 视频地址
stackoverflow上也有人讨论这个问题,视频也是在这个问题下面看到的。
前段时间在项目用到 AppBarLayout 加 RecyclerView的时候,产品经理和设计师对这个效果都不满意。
so....只能填坑了。

初步解决

stackoverflow 上也有提及这个问题主要是由于 consumed 有时候在 onNestedFling 中计算不对导致的。
因此可以重写AppBarLayout的Behavior
这个答案可以解决这个问题 http://stackoverflow.com/a/32454407
当然记得在xml 为 AppBarLayout 设置上自定义的Behavior

更进一步解决

还有一种情况可能体验不是很好,就是在 往上 fling 的时候,AppBarLayout没有拉下来,需要在拉一次才能下来,那时产品经理对这个也不是很满意。
这种情况下 consumed 的值为 true 即时经过修正之后也是为 true ,然后在看
super.onNestedFling 源码 发现这时候也是不会调用 fling 的。事实上大部分这时候 AppBarLayout 不去fling也是对的,因为这时候 AppBarLayout 应该在可见的视图之外。
于是后来打算去监听 RecyclerView的滚动,在滚动到第一条的时候展开 AppBarLayout,发现效果还不错

list.addOnScrollListener(new RecyclerView.OnScrollListener() {
     @Override    
     public void onScrollStateChanged(RecyclerView recyclerView, int newState) {        
        super.onScrollStateChanged(recyclerView, newState);        
        if (newState == RecyclerView.SCROLL_STATE_IDLE) {            
        int firstVisiblePosition = layoutManager.findFirstCompletelyVisibleItemPosition();            
        if (firstVisiblePosition == 0) {
           appbar.setExpanded(true, true);            
        }        
     }    
}});

这时候滚动到顶部的时候,RecyclerView 有个波纹效果,导致看起来比较别扭,
给 RecyclerView 设置以下属性即可

android:overScrollMode="never"

其他方案

github 上有个库也是解决这个问题的 smooth-app-bar-layout
当然解决的原理跟本文相差甚远,有兴趣可以阅读下,我自己也有用过,不过这个库比较蛋疼的就是得为RecyclerView 设置一个 head item, 这个 item 的高度必须跟 AppBarLayout 一样的高度,所以对于 wrap_content 就比较麻烦了,当然,这个跟这个库的实现思路有关系。

最后,希望本文能给准备入坑的同学少走一点弯路

ps (我目前用的最新 support 包 26.1.0 版本 已经基本修复这个问题)

相关文章

网友评论

  • 我是解忧鸭铺鸭:升级到26.1.0之后 能否自己设置关闭或打开smooth滑动 有些页面不关闭的话,我自定义的Behavior好像会出问题 老api的嵌套滑动回调不执行了 用新api又会抖动
  • 爆发小宇:26.1.0 这个办法,我load 失败了,
    Error:Failed to resolve: com.android.support:design:26.0.1,请问你是怎么加载成功的
    我是解忧鸭铺鸭:android studio3.0
    爆发小宇:修改一下,Error:Failed to resolve: com.android.support:design:26.1.0
  • 码字与律动:谢谢楼主。
  • 工藤一号:一波666666送给你!太赞了!已关注已点赞!
  • 晚睡晚起的:appbar向下滑的时候 收缩后就停在上边了 recycleview要再滑一次才能滑动 这个有办法解决吗
    晚睡晚起的:@战火弄脏她的泪光 没有处理,..你处理了吗
    码字与律动:你好,朋友,这个问题你解决了吗?
  • 欢乐的乐:试了这么多方法,终于在你这里解决了 谢谢啊:sob:
  • tomato_wl:作者你好,我现在是RecyclerView嵌套RecyclerView的布局 但是linearLayoutManager.findFirstCompletelyVisibleItemPosition() 得到的返回值是-1,如果没有滑动到底部,这个值一直是-1,只有当滑动到底部的时候才能获取到 ,请问是什么原因呢
    lguipeng:@换个名字_f0e9 升级到最新的support包
    045acae7632d:我遇到了同样的情况,请问你解决了吗?
  • 非典型的程序员:CoordinatorLayout + viewpager + recyclerview

    如果是上面这种情况,该张某解决?recyclerview是嵌套在viewpager里面的




    非典型的程序员:@lguipeng 我升级到24.1.1就有这个方法了,不过我发现个问题,就是当出现firstPosition = 0的时候会自动“弹”到顶部,而不是平滑到顶部
    也就是说要滑动到position>0的时候,头部的布局才会隐藏,不然都是会自动弹回顶部
    lguipeng: @axkza 你的是哪个版本的支持库?我的24.2.1还有的
    非典型的程序员:@lguipeng 貌似找不到这个方法了 appbar.setExpanded(true, true);
  • 57855e86d40d:smooth-app-bar-layout太不人性化了 我现在倒是希望Google赶紧修复这个bug

本文标题:解决 RecyclerView AppBarLayout 滑动

本文链接:https://www.haomeiwen.com/subject/nvgedttx.html