CoordinatorLayout + AppBarLayout + RecyclerView,滚动到最底部延迟的坑

本文主要是介绍CoordinatorLayout + AppBarLayout + RecyclerView,滚动到最底部延迟的坑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

随着开发功能越来越复杂,我们使用的控件也越来越多。今天给大家带来一个找了好久解决掉的坑。

目前我们的APP首页使用了联动控件,CoordinatorLayout + AppBarLayout + RecyclerView。这个组合相信用过的都知道,坑其实挺多的,有造成屏幕抖动的,有造成部分白屏的,还有就是我解决的这个,快速滚动到底部,延迟很久才会回调RecyclerView的onScrollStateChanged。可能还有别的坑,目前就这几个。

先说一下原因吧,具体不知道是design的哪个版本升级,里面引入了惯性下滑的概念,滑动的速度越快,下滑的时间越长,就会让我们的界面实际上已经滑动到最底部了,但是还是卡在了下滑的过程之中,等惯性下滑的触发结束以后,才会触发RecyclerView的onScrollStateChanged。就会导致我们的RecyclerView明明已经滑动到最底部,需要去加载下一页数据,却一直卡着不动。

解决方法:其实明白了原因,网上关键字一搜解决方法还是很多的。主要是当碰到这个问题的时候,一直没有准确定位到原因。

分享一下我的调查和处理吧

1.我先是认为是应用的部分UI相关的处理比较复杂导致了应用的卡顿,然后将所有RecyclerView对于Ui相关的处理全部注释掉,发现没有任何改善。

2.分析是因为接口请求等太多太复杂,但是由于接口全部都是异步的,测试的时候心里预期80%不是这个引起的,注释完代码然后测试,结果正合我的预期。

3.由于RecyclerView中也实现了很多onScrollStateChanged 和onScroll 方法的重写,当时是怀疑自己写的onScroll 或者onScrollStateChanged方法内部处理导致了super的onScroll 和onScrollStateChanged 被拦截。同样注释代码测试,仍然不是。

4.最后看了一下所有代码都快注释完了,然后重新分析是不是布局导致的。然后看了这个联动控件,猜想可能是AppBarLayout 的滚动事件和RecyclerView的滚动事件相互冲突了。然后我把CoordinatorLayout注释了,运行,发现RecyclerView的回调正常了。然后有了上述问题原因的分析。最后成功解决了问题。

下面附上解决方法。自定义一个behavior类继承系统的AppBarLayout.Behavior ,加速结束惯性下滑的回调,当滑动到顶,或者滑动到底就认为滑动结束。下面附上代码。

public class ScrollAppBarLayoutBehavior extends AppBarLayout.Behavior {public ScrollAppBarLayoutBehavior() {super();}public ScrollAppBarLayoutBehavior(Context context, AttributeSet attrs) {super(context, attrs);}@Overridepublic void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,View target, int dx, int dy, int[] consumed, int type) {super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);stopNestedScrollIfNeeded(dy, child, target, type);}@Overridepublic void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target,int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int type) {super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);stopNestedScrollIfNeeded(dyUnconsumed, child, target, type);}private void stopNestedScrollIfNeeded(int dy, AppBarLayout child, View target, int type) {if (type == ViewCompat.TYPE_NON_TOUCH) {final int currOffset = getTopAndBottomOffset();if ((dy < 0 && currOffset == 0) || (dy > 0 && currOffset == -child.getTotalScrollRange())) {ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH);}}}
}

重写的类写好以后,在xml里面AppBarLayout控件中使用我们自定义的ScrollAppBarLayoutBehavior即可。

<android.support.design.widget.AppBarLayoutandroid:id="@+id/appbar"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_behavior=".demo.ScrollAppBarLayoutBehavior" >

———————————————重要分割线———————————————————

补充一下.看到很多留言说,关于数据不够多或者空白的时候,上滑的时候,会导致大片空白问题.以及可能会滑动不回来的问题.

之前我这边没有复现,一直也比较忙,没时间帮忙看.最近在用的时候,正好也碰到了.把我这边的解决方案和大家共享一下.
一个个说.如果是空白界面,一般我们会使用统一的空白界面.由于显示着空白界面隐藏了recycleview,空白页面没有实现滑动功能,所以在整个头部滑动到最顶上的时候,很可能就滑不下来了.我这边做了最简单的处理.
直接增加了一个是否允许滑动的开关.
public void setEnable(boolean enable) {
        if (appbar == null) {
            return;
        }
        View mAppBarChildAt = appbar.getChildAt(0);
        AppBarLayout.LayoutParams mAppBarParams = (AppBarLayout.LayoutParams) mAppBarChildAt.getLayoutParams();
        if (enable) {
            mAppBarParams.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
                    | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED);
        } else {
            mAppBarParams.setScrollFlags(0);
        }
        mAppBarChildAt.setLayoutParams(mAppBarParams);
    }
此时可能会出现一个bug,这个appbar底部会有透明框.在xml 设置app:elevation="0dp" 就可以解决了.
同理,如果数据不够多的时候,可以理解为顶部折叠控件完全折叠,当然就只剩下底部的recycleview了.这个控件就是把顶部当成一个折叠控件.那么最好的解决方案,当然也是数据量少的时候,直接禁止上滑就好了.禁止滑动的逻辑就在上面.

这篇关于CoordinatorLayout + AppBarLayout + RecyclerView,滚动到最底部延迟的坑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877461

相关文章

ActiveMQ—消息特性(延迟和定时消息投递)

ActiveMQ消息特性:延迟和定时消息投递(Delay and Schedule Message Delivery) 转自:http://blog.csdn.net/kimmking/article/details/8443872 有时候我们不希望消息马上被broker投递出去,而是想要消息60秒以后发给消费者,或者我们想让消息没隔一定时间投递一次,一共投递指定的次数。。。 类似

MySQL主从同步延迟原理及解决方案

概述 MySQL的主从同步是一个很成熟的架构,优点为: ①在从服务器可以执行查询工作(即我们常说的读功能),降低主服务器压力; ②在从主服务器进行备份,避免备份期间影响主服务器服务; ③当主服务器出现问题时,可以切换到从服务器。 相信大家对于这些好处已经非常了解了,在项目的部署中也采用这种方案。但是MySQL的主从同步一直有从库延迟的问题,那么为什么会有这种问题。这种问题如何解决呢? MyS

UniApp实现漂亮的音乐歌词滚动播放效果

在现代的音乐播放应用中,歌词的展示和滚动播放已经成为了一个非常常见的功能。今天,我们将通过UniApp来实现一个漂亮的歌词滚动播放功能。我们将使用UniApp提供的组件和API来完成这个任务。 页面结构 在页面的模板部分,我们需要创建一个音频播放器和歌词展示区域。使用<scroll-view>组件来实现歌词的滚动效果。 <template><view class="audio-co

【Unity-Lua】音乐播放器循环滚动播放音乐名

前言:Unity中UI节点 图1 如上所示,一开始本来是打算用ScrollView做的,觉得直接计算对应的文本位置就行,所以没用ScrollRect来做,可以忽略Scroll,Viewport这些名字。如下图:需要在一个背景Image组件上添加上Mask组件来显示固定位置的文本显示。 图2 图3 并且需要在要显示的文本上挂载Content Size Filter组件,但是这儿会有个坑

WebAPI(二)、DOM事件监听、事件对象event、事件流、事件委托、页面加载与滚动事件、页面尺寸事件

文章目录 一、 DOM事件1. 事件监听2. 事件类型(1)、鼠标事件(2)、焦点事件(3)、键盘事件(4)、文本事件 3. 事件对象(1)、获取事件对象(2)、事件对象常用属性 4. 环境对象 this5. 回调函数 二、 DOM事件进阶1. 事件流(1)、 捕获阶段(2)、 冒泡阶段(3)、 阻止冒泡(4) 、阻止元素默认行为(5) 、解绑事件 2. 事件委托3. 其他事件(1)、页面加

【Android】NestedScrollView的简单用法与滚动冲突、滑动冲突

一、NestedScrollView 1. 什么是 NestedScrollView NestedScrollView 是 Android 中一个用于处理垂直方向滚动的布局组件,它继承自 FrameLayout,同时支持嵌套滑动(Nested Scrolling)机制。相比于传统的 ScrollView,NestedScrollView 专为解决嵌套滚动冲突问题设计,能够与其他支持嵌套滑动的子

Flink全链路延迟的测量方式和实现原理

点击上方蓝色字体,选择“设为星标” 回复”面试“获取更多惊喜 本文已经加入「大数据成神之路PDF版」中提供下载。你可以关注公众号,后台回复:「PDF」 即可获取。 一、背景 Flink Job端到端延迟是一个重要的指标,用来衡量Flink任务的整体性能和响应延迟(大部分流式应用,要求低延迟特性)。 通过流处理引擎竞品对比,我们发现大部分流计算引擎产品,都在告警监控页面,集成了全链路时延指标

Jquery实现广告滚动

当页面的滚动条上下移动时,飘浮广告随着滚动条的滚动而上移或者下移,要明白两点,第一:放广告的层最好采用绝对定位,它的位置应该随着滚动条的改变而上下移动,滚动条的滚动促发的是onscroll事件,广告条所在的层的top值就是滚动条的高度,具体代码如下: <html><head><meta http-equiv="Content-Type" content="text/html; charset

dispatch_after 的延迟执行分析

dispcth_after 是将block 中的任务延迟添加到它将要执行的队列中去,而并不一定添加到队列中就立即会去执行任务。 图中表示是在5秒中后将任务添加到主队列中,如果主队列中还有另外的任务假设A、B 要执行,那么这个任务会在任务A、B 执行完后才会开始执行。 验证的代码如下: dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int

SpringBoot教程(十五) | SpringBoot集成RabbitMq(死信队列、延迟队列)

SpringBoot教程(十五) | SpringBoot集成RabbitMq(死信队列、延迟队列) (一)死信队列使用场景具体用法前提示例: (二)延迟队列使用场景方法一:通过死亡队列实现方法二:通过延迟消息插件(rabbitmq_delayed_message_exchange)实现 (一)死信队列 死信队列是一个重要的概念,用于处理那些因各种原因无法被正常消费的消息。 它