SwipeRefreshLayout无法下拉刷新了

2024-05-28 12:18

本文主要是介绍SwipeRefreshLayout无法下拉刷新了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 问题

某次项目上线前,QA的妹纸忽然发现一个严重的bug,列表无法进行下拉刷新了。使用场景是当前列表数据为空,或者请求失败时,又没有加载到缓存数据的情况,EmptyView页面就无法进行下拉刷新了。关于这个问题,我曾重点解决过,所以当妹纸提出这个bug时,作为程序员的职业习惯第一反应是:这不可能,你看我这好着呢

然而经过几轮测试发现问题是真实存在的,这么简单的一个SwipeRefreshLayout为什么出了这么多幺蛾子呢

2.问题背景

最开始采用SwipeRefreshLayout作为下拉刷新控件,但是产品经理还没来得及定义EmptyView页长什么样就跑路了,所以这个问题就交给程序员自己解决了

最简单的方案就是在Empty页中间放一个按钮,请求失败或者无网络的时候分别提示用户点击重试或者设置网络,这也是大多数APP的选择。

不过即便请求失败或者空数据的情况下,仍然采用下拉刷新的操作来进行retry,在交互上可以保证用户习惯的一致性,而且滑动操作也比点击操作有更好的体验,也是交互和设计的趋势所向

当时第一版开发时间特别紧,所以关于这个EmptyView的实现方案特别挫。直接在xml里包了两个SwipeRefreshLayout,一个用来下拉刷新列表,一个用来下拉刷新EmptyView,然后在代码里控制二者的显示与隐藏。方案虽然很挫,但也没出什么大问题,就这么作为临时方案先用着

第二版的时候把这个方案替换掉了,去掉了EmptyView外面包裹的SwipeRefreshLayout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true">
<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeLayout"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><android.support.v7.widget.RecyclerView
          android:id="@+id/list_view"android:layout_width="match_parent"android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout><TextView
        android:id="@+id/error_view"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="center"android:textColor="@color/subhead_text_color"android:textSize="@dimen/primary_tip_size"android:visibility="gone" />
</RelativeLayout>

直接这样,EmptyView依然可以下拉刷新,这里依赖的原理是点击事件的穿透,即便当前显示在上层的视图是EmptyView,如果不给EmptyView添加任何事件,那么事件会向下传递,传递给下面的SwipeRefreshLayout,有时候这种奇技淫巧还是挺有用的

然后这个方案就一直延续着,直到开头提到的QA妹纸发现无法下拉刷新的bug为止,都没有发现什么问题。那这个bug到底是什么原因引起的呢?

3. 思路(我觉得蛮重要的)

我第一反应是,有人动我代码了,于是我compare了当前节点与上次发版的节点,代码一毛一样,没有人动我代码,但是线上的就OK啊。刚开始我跟QA妹纸打包票,半个小时解决问题,而实际上最后和同事们花了近半天时间才解决。

问题走进了死胡同,首先是看了半个小时代码,无法准确定位问题。compare了两个节点的代码,依然无法定位,那还是只能采用笨办法了,排除法。上次发版距本次发版,这中间已经产生了几十个commit,到底是哪次commit后出现了这个问题,这是第一个要定位的问题,于是乎一一checkout验证,当然这也是有技巧的,虽然没验证过到底怎样的查找方式会比较快,习惯性的在这几十个commit中来了个二分查找。每次checkout编译运行测试也是很耗时的,而且这个工作很枯燥,只能发动大家一块来找茬啦

找了好大一会,终于定位到了一个commit,这个commit 之前OK,而之后就悲剧了。那毫无疑问就是它搞得鬼,但这个commit毫不起眼,根本没有什么伤筋动骨的修改。那如果代码上没有大修改,就要注意下AndroidManifeset和gradle了。gradle中增加了些看似无关紧要的引用,肉眼也实在看不出有什么问题,但如果把这些新增的引用包去掉,问题马上就解决了。但新增的这些包与SwipeRefreshLayout可是八竿子打不着啊,但SwipeRefreshLayout是android.support.v4包里的控件,会不会是support.v4包更换了新的版本?

展开External Libraries 发现果然有两个support.v4包

这里写图片描述

难道是这两个包里的SwipeRefreshLayout实现不太一样,或者有做改动?

找到源码一探究竟,拉出support.v4-23.0.1和support.v4-23.3.0里的SwipeRefreshLayout源码,一看行数都不一样,前者1152行,后者1163行。我勒个去还真是做了修改,难道是升级的时候没有向下兼容吗?compare了下两个版本的代码,发现事件分发那里确实做了些修改

这里写图片描述

4. 解决办法

猜想大概是这个原因,利用Click-Through来实现下来刷新不能奏效了。但是我仍然想用以前的方案,怎么办呢?
有两个办法,一个是指定使用老版本的support.v4包。二是把老版本的代码copy出来放到自己工程里。最后我们采用了比较优雅一点的方式,在gradle里强制指定了版本

configurations.all {resolutionStrategy {force 'com.android.support:support-v4:23.0.1'}
}

最后一个问题,为什么会有两个support-v4包呢?刚开始的时候用recyclerview,SwipeRefreshLayout这些空间的时候导入了一个support-v4包,这个版本相对较低,是support-v4:23.0.1,后来一直没有更新。随着项目的进行,另外的同学在导入其他第三方包的时候,这个第三方包依赖了一个比较新的support-v4包,support.v4-23.3.0。所以这个时候SwipeRefreshLayout默认使用了比较新的额代码,就导致了开头所提到的那个bug。友情提示:更新引用包是有很大风险的,一定要多测试。有时间再说下另外一次更新包挖的坑

这篇关于SwipeRefreshLayout无法下拉刷新了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

三国地理揭秘:为何北伐之路如此艰难,为何诸葛亮无法攻克陇右小城?

俗话说:天时不如地利,不是随便说说,诸葛亮六出祁山,连关中陇右的几座小城都攻不下来,行军山高路险,无法携带和建造攻城器械,是最难的,所以在汉中,无论从哪一方进攻,防守方都是一夫当关,万夫莫开;再加上千里运粮,根本不需要打,司马懿只需要坚守城池拼消耗就能不战而屈人之兵。 另一边,洛阳的虎牢关,一旦突破,洛阳就无险可守,这样的进军路线,才是顺势而为的用兵之道。 读历史的时候我们常常看到某一方势

ORACLE 11g 创建数据库时 Enterprise Manager配置失败的解决办法 无法打开OEM的解决办法

在win7 64位系统下安装oracle11g,在使用Database configuration Assistant创建数据库时,在创建到85%的时候报错,错误如下: 解决办法: 在listener.ora中增加对BlueAeri-PC或ip地址的侦听,具体步骤如下: 1.启动Net Manager,在“监听程序”--Listener下添加一个地址,主机名写计

使用Qt编程QtNetwork无法使用

使用 VS 构建 Qt 项目时 QtNetwork 无法使用的问题 - 摘叶飞镖 - 博客园 (cnblogs.com) 另外,强烈建议在使用QNetworkAccessManager之前看看这篇文章: Qt 之 QNetworkAccessManager踏坑记录-CSDN博客 C++ Qt开发:QNetworkAccessManager网络接口组件 阅读目录 1.1 通用API函数

Clion不识别C代码或者无法跳转C语言项目怎么办?

如果是中文会显示: 此时只需要右击项目,或者你的源代码目录,将这个项目或者源码目录标记为项目源和头文件即可。 英文如下:

解决ubuntu系统无法与FinalShell无法连接问题

问题 解决方案 先下载ubuntu网络工具 sudo apt install net-tools 输入密码 下载完成后进入管理员模式查看密码 sudo -i hostname -I 查看IP 得到ip地址后再继续安装 openssh-server 插件 sudo apt-get install openssh-server 问题解决 尝试连接Fina

gazebo 已加载模型但无法显示

目录 写在前面的话问题一:robot_state_publisher 发布机器人信息失败报错一 Error: Error document empty.报错二 .xcaro 文件中有多行注释成功启动 问题二:通过 ros2 启动 gazebo 失败成功启动 问题三:gazebo 崩溃和无法显示模型问题四: 缺少 robot_description 等话题正确的输出 写在前面的话

在Webmin上默认状态无法正常显示 Mariadb V11.02及以上版本

OS: Armbian OS 24.5.0 Bookworm Mariadb V11.02及以上版本 Webmin:V2.202 小众问题,主要是记录一下。 如题 Webmin 默认无法 Mariadb V11.02及以上版本 如果对 /etc/webmin/mysql/config 文件作相应调整就可以再现Mariadb管理界面。 路径+文件:/etc/webmin/mysql/config

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题 GitHub Pages是一个直接从GitHub存储库托管的静态站点服务,‌它允许用户通过简单的配置,‌将个人的代码项目转化为一个可以在线访问的网站。‌这里使用flutter build web来构建web发布到GitHub Pages。 最近通过flutter build web,通过发布到GitHu

关于iReport5.6.0无法正常启动或者闪退或者JDK8不兼容的解决方案

我下载了iReport5.6.0 版本的,启动不起来;jdk 1.8 下载iReport5.6.0地址:https://download.csdn.net/download/u013456370/10589765 参考链接:https://blog.csdn.net/erlian1992/article/details/76359191?locationNum=6&fps=1 如果是停留在这

Eclipse发布Maven项目到tomcat,无法加载到lib文件夹下的jar包

BMS 解决方法: 当我们发布web项目到tomcat时,访问地址时会报一个classnotfound的错误,但是eclipse中的项目中都已经添加了相应的类,有一种比较容易犯的错误是,你没有把额外所需的jar包加到tomcat中的lib文件夹中,在这里介绍一种在项目中直接添加jar包到lib目录下:  右键已创建的web项目——properties属性——点击Deployment Assem