关于PullToRefreshView下拉刷新失效问题
一、问题原因
昨天,突然一个问题丢在了我的头上,用户反馈说某某界面下拉刷新不好使啊,怎么回事。二话不说直接运行项目,经过测试,发现果然不好使。一看代码提交日期好家伙2020年,百思不得其解,为啥20年的下拉刷新不好使,到现在才反馈。
还是看问题原因吧。
看了下下拉刷新框架是PullToRefreshView(好像没有用过这个框架),经过测试发现下拉手势怎么都不能回调到刷新回调,
只能断点调试了。
有几个方向可以试探下。
- ViewPager拦截我们的触摸事件了,导致触摸事件没有下发到我们的listView中
- 没有正确注册刷新回调接口
- ListView本身没有处理好下拉事件
以上都是几个猜想方向,我们一一验证。
我们就直接注册ListView触摸事件回调,就可以验证上述猜想。经过验证发现,以上猜想都错了。那么问题是出在哪呢。
跟着代码一步一步走下去就能发现原因了。
二、问题分析
经过调试,最终定位到PullToRefreshBase这个类中。在这个类的onInterceptTouchEvent方法中找到了处理手势的逻辑。
public final boolean onInterceptTouchEvent(MotionEvent event) {if (!isPullToRefreshEnabled()) {return false;}final int action = event.getAction();if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {mIsBeingDragged = false;return false;}if (action != MotionEvent.ACTION_DOWN && mIsBeingDragged) {return true;}switch (action) {case MotionEvent.ACTION_MOVE: {// If we're refreshing, and the flag is set. Eat all MOVE eventsif (!mScrollingWhileRefreshingEnabled && isRefreshing()) {return true;}if (isReadyForPull()) {final float y = event.getY(), x = event.getX();final float diff, oppositeDiff, absDiff;// We need to use the correct values, based on scroll// directionswitch (getPullToRefreshScrollDirection()) {case HORIZONTAL:diff = x - mLastMotionX;oppositeDiff = y - mLastMotionY;break;case VERTICAL:default:diff = y - mLastMotionY;oppositeDiff = x - mLastMotionX;break;}absDiff = Math.abs(diff);if (absDiff > mTouchSlop && (!mFilterTouchEvents || absDiff > Math.abs(oppositeDiff))) {if (mMode.showHeaderLoadingLayout() && diff >= 1f && isReadyForPullStart()) {mLastMotionY = y;mLastMotionX = x;mIsBeingDragged = true;if (mMode == Mode.BOTH) {mCurrentMode = Mode.PULL_FROM_START;}} else if (mMode.showFooterLoadingLayout() && diff <= -1f && isReadyForPullEnd()) {mLastMotionY = y;mLastMotionX = x;mIsBeingDragged = true;if (mMode == Mode.BOTH) {mCurrentMode = Mode.PULL_FROM_END;}}}}break;}case MotionEvent.ACTION_DOWN: {if (isReadyForPull()) {mLastMotionY = mInitialMotionY = event.getY();mLastMotionX = mInitialMotionX = event.getX();mIsBeingDragged = false;}break;}}return mIsBeingDragged;}
到这里就很简单了,给每一个判断都打上断点,一步步走。最后发现mIsBeingDragged这个值为false。这就导致在onTouchEvent中并不会执行我们的刷新逻辑。
switch (event.getAction()) {//...省略部分代码case MotionEvent.ACTION_MOVE: {if (mIsBeingDragged) {mLastMotionY = event.getY();mLastMotionX = event.getX();//处理刷新和加载事件pullEvent();return true;}break;}case MotionEvent.ACTION_DOWN: {if (isReadyForPull()) {mLastMotionY = mInitialMotionY = event.getY();mLastMotionX = mInitialMotionX = event.getX();return true;}break;}//...省略部分代码
}
可以看到在move事件中,并不会执行我们刷新逻辑。
到这里就可以明白肯定是在onInterceptTouchEvent中,部分逻辑判断失败了,导致mIsBeingDragged值为false。
重新回到上一个逻辑中,就可以发现isReadyForPullStart()方法返回值为false就无法执行到mIsBeingDragged赋值为true的逻辑。
最终会执行到isFirstItemVisible()中,一起来看看吧。
private boolean isFirstItemVisible() {final Adapter adapter = mRefreshableView.getAdapter();if (null == adapter || adapter.isEmpty()) {if (DEBUG) {Log.d(LOG_TAG, "isFirstItemVisible. Empty View.");}return true;} else {/*** This check should really just be:* mRefreshableView.getFirstVisiblePosition() == 0, but PtRListView* internally use a HeaderView which messes the positions up. For* now we'll just add one to account for it and rely on the inner* condition which checks getTop().*/if (mRefreshableView.getFirstVisiblePosition() <= 1) {final View firstVisibleChild = mRefreshableView.getChildAt(0);if (firstVisibleChild != null) {return firstVisibleChild.getTop() >= mRefreshableView.getTop();}}}return false;}
最后就是看这句代码return firstVisibleChild.getTop() >= mRefreshableView.getTop();在debug下计算这段,就会发现firstVisibleChild.getTop()的值为0,而mRefreshableView.getTop()的值为30,什么情况呢。
再去看源码会发现,mRefreshableView其实就是我们的ListView。那么这里判断的就是第一个item距离上边界的距离和ListView距离上边界的距离。
那么这里我们就要去找找为什么ListView的距离要比item的距离大。
在项目中找到了如下代码,没想到简简单单的一句代码影响这么大。
lp.setMargins(0, ViewUtil.dip2px(mActivity, 10), 0, 0);
mListview.setLayoutParams(lp);
注释这段设置margin的代码,转为在上一个控件设置margin或者在item中设置margin。不能下拉刷新就完美解决了,泰裤辣!!!
相关文章:
关于PullToRefreshView下拉刷新失效问题
一、问题原因 昨天,突然一个问题丢在了我的头上,用户反馈说某某界面下拉刷新不好使啊,怎么回事。二话不说直接运行项目,经过测试,发现果然不好使。一看代码提交日期好家伙2020年,百思不得其解,…...
JAVA开发中的六大原则
JAVA开发中的六大原则,也被称为SOLID原则,是软件开发中常用的一组设计原则。这些原则提供了实现高质量、易于维护和可扩展软件的基本策略。 以下是JAVA开发中的六大原则以及它们的详细说明: 单一职责原则(Single Responsibility…...
Matplotlib 安装
Matplotlib 安装 本章节,我们使用 pip 工具来安装 Matplotlib 库,如果还未安装该工具,可以参考python 怎么使用pip进行包管理。 安装 matplotlib 库: pip install matplotlib 安装完成后,我们就可以通过 import 来…...
CF - Li Hua and Pattern
题意:给出了矩阵,里面每个位置分为蓝色或红色(数据上用1和0体现了),给出了一个操作次数,每次可以改变一个坐标的颜色,问能否通过操作使得图像旋转180度后不变。 解:很容易想到&…...
重磅!阿里云云原生合作伙伴计划全新升级:加码核心权益,与伙伴共赢新未来
在今天的 2023 阿里云合作伙伴大会上,阿里云智能云原生应用平台运营&生态业务负责人王荣刚宣布: “阿里云云原生合作伙伴计划”全新升级。他表示: 云原生致力于帮助企业客户最大限度的减轻运维工作,更好的实现敏捷创新&#x…...
OSCP-Escape(gif绕过)
目录 扫描 WEB 扫描 sudo nmap 192.168.233.113 -p- -sS -sVPORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) 80/tcp open http Apache httpd 2.4.29 ((Ubuntu)) 8080/tcp open http Apache…...
iMazing2023最新免费版iOS设备管理软件
iMazing是一款功能强大的iOS设备管理软件,它可以帮助用户备份和管理他们的iPhone、iPad或iPod Touch上的数据。除此之外,它还可以将备份数据转移到新的设备中、管理应用程序、导入和导出媒体文件等。本文将详细介绍iMazing的功能和安全性,并教…...
Git上传文件代码到GitHub
删除线上git:删除GitHub仓库里的文件夹_阿巴资源站的博客-CSDN博客 1. 创建空文件夹 2. cd 到本文件夹 3. git init ,初始化,在本地创建一个Git仓库 4. 同时按住“ Command Shift . ”三个按键,即可查看当下文件夹中的隐藏文件 5. 克隆…...
JavaScript概述二(Date+正则表达式+Math+函数+面向对象)
1.Date 1.1 new一个Date对象表示当前系统时间 var nownew Date(); console.log(now);1.2 根据传入的时间格式表示时间 var date1new Date(2023-4-20 00:16:40); console.log(date1); 1.3 传入时间毫秒数,返回从1900年1月1日8时(东八区)X分X…...
一个朋友弄来的,太牛了,特别是后面内容,不看不知道,一看吓一跳,电话,热线
一个朋友弄来的,太牛了,特别是后面内容,不看不知道,一看吓一跳,我也收藏一下: 工商银行 95588 建设银行 95533 农业银行 95599 中国银行 95566 交通银行 95559 浦发银行 95528 民生银行 95568 兴业银行 955…...
VGA协议实践
文章目录 前言一、VGA接口定义与传输原理1、VGA接口定义2、传输原理3、不同分辨率对应不同参数 二、Verilog编程1、VGA显示彩色条纹2、VGA显示字符3、输出一幅彩色图像4、Quartus操作1、添加PLL核2、添加ROM核 三、全部代码四、总结五、参考资料 前言 VGA的全称是Video Graphi…...
毕业5年的同学突然告诉我,他已经是年薪30W的自动化测试工程师....
作为一名程序员,都会对自己未来的职业发展而焦虑。一方面是因为IT作为知识密集型的行业,知识体系复杂且知识更新速度非常快,“一日不学就会落后”。 另外一方面,IT又是劳动密集型的行业,不仅业人员多,而且个…...
操作系统原理 —— 进程有哪几种状态?状态之间如何切换?(七)
进程的五种状态 首先我们一起来看一下进程在哪些情况下,会有不同的状态表示。 创建态、就绪态 当我们刚开始运行程序的时候,操作系统把可执行文件加载到内存的时候,进程正在被创建的时候,它的状态是创建态,在这个阶…...
可算是熬出头了,测试4年,费时8个月,入职阿里,涨薪14K
前言 你的努力,终将成就无可替代的自己。 本科毕业后就一直从事测试的工作,和多数人一样,最开始从事点点点的工作,看着自己的同学一步一步往上走,自己还是在原地踏步,说实话这不是自己想要的状态。 一年半…...
5款十分小众的软件,知道的人不多但却很好用
今天推荐5款十分小众的软件,知道的人不多,但是每个都是非常非常好用的,有兴趣的小伙伴可以自行搜索下载。 1.视频直播录制——OBS Studio OBS Studio可以让你轻松地录制和直播你的屏幕、摄像头、游戏等内容。你可以使用OBS Studio来创建多种…...
Linux驱动开发:uboot启动流程详解
前言:uboot作为Linux驱动开发的 “三巨头” 之一,绝对是一座绕不开的大山。当然,即使不去细致了解uboot启动流程依旧不影响开发者对uboot的简单移植。但秉持着知其然知其所以然的学习态度,作者将给读者朋友细致化的过一遍uboot启动…...
分治与减治算法实验: 排序中减治法的程序设计
目录 前言 实验内容 实验目的 实验分析 实验过程 流程演示 写出伪代码 实验代码 代码详解 运行结果 总结 前言 本文介绍了算法实验排序中减治法的程序设计。减治法是一种常用的算法设计技术,它通过减少问题的规模来求解问题。减治法可以应用于排序问题&…...
leetcode两数、三数、四数之和
如有错误,感谢不吝赐教、交流 文章目录 两数之和题目方法一:暴力两重循环(不可取)方法二:HashMap空间换时间 三数之和题目方法一:当然是暴力破解啦方法二:同两数之和的原理,借助Has…...
使用Docker部署wikitten个人知识库
使用Docker部署wikitten个人知识库 一、wikitten介绍1.wikitten简介2.wikitten特点 二、本地实践环境介绍三、本地环境检查1.检查Docker服务状态2.检查Docker版本 四、部署wikitten个人知识库1.创建数据目录2.下载wikitten镜像3.创建wikitten容器4.查看wikitten容器状态5.检查w…...
【MYSQL】Java的JDBC编程(idea连接数据库)
1. 配置 (1)新建一个项目 (2)Build System 那里选择Maven,下一步Create (3)配置pom.xml文件 首先查看自己的MYSQL版本:进入MySQL命令窗口 我的MYSQL版本是8.0版本的. 下一步,…...
开发环境配置实战:通过Anaconda Prompt高效管理虚拟环境与Jupyter内核
1. 为什么需要Anaconda Prompt管理虚拟环境 作为数据科学领域的开发者,我经历过无数次Python环境混乱带来的痛苦。记得有一次在交付项目前,突然发现本地运行的模型在服务器上完全无法复现,排查了半天才发现是numpy版本不兼容的问题。这种经历…...
基于 PLC 的自动门控制系统设计与仿真程序探索
基于plc的自动门控制系统设计 仿真程序资料在自动化控制领域,基于 PLC(可编程逻辑控制器)的自动门控制系统应用广泛。今天咱就唠唠这基于 PLC 的自动门控制系统设计以及相关的仿真程序资料。 自动门控制系统设计需求 自动门要实现多种功能&a…...
Arduino驱动OV7670图像传感器:底层时序与跨平台实现
1. Arduino_OV767X 库深度解析:OV7670 CMOS 图像传感器在 Arduino 平台上的底层驱动与工程实践OV7670 是 OmniVision(现属韦尔半导体)于 2000 年代初推出的超低功耗、单芯片 QVGA(320240)彩色 CMOS 图像传感器。其采用…...
从“能用”到“好用”:给你的GoLand 2022.2.3装上这些插件,开发体验大不同
从“能用”到“好用”:给你的GoLand 2022.2.3装上这些插件,开发体验大不同 每天面对代码编辑器的时间可能比面对家人还长——这不是玩笑,而是许多开发者的真实写照。当GoLand从单纯的代码工具转变为你的"数字工作台",插…...
2025 年勒索软件隐匿化攻击演进与行为基线防御研究
摘要 据 Talos 2025 年度网络安全回顾报告显示,勒索软件攻击已从暴力突破转向合法访问隐匿渗透,攻击者依托钓鱼、有效账号与系统自带管理工具实现无感知横向移动,传统边界防护显著失效。2025 年数据表明,约 40% 初始访问源于网络钓…...
TouchGal终极指南:打造纯净Galgame社区的完整解决方案
TouchGal终极指南:打造纯净Galgame社区的完整解决方案 【免费下载链接】kun-touchgal-next TouchGAL是立足于分享快乐的一站式Galgame文化社区, 为Gal爱好者提供一片净土! 项目地址: https://gitcode.com/gh_mirrors/ku/kun-touchgal-next TouchGal是一个专为…...
TFLint Docker终极指南:在容器中轻松运行Terraform代码检查
TFLint Docker终极指南:在容器中轻松运行Terraform代码检查 【免费下载链接】tflint A Pluggable Terraform Linter 项目地址: https://gitcode.com/gh_mirrors/tf/tflint TFLint是一个可插拔的Terraform代码检查工具,帮助开发者发现Terraform配置…...
镜像视界|无感定位终极形态:无需设备的人体空间定位技术突破——基于视频空间反演与多摄像机融合的无标签定位体系封面主视觉(建议)4一、终极问题:定位为什么始终依赖“设备”在传统技术体系中,“
镜像视界|无感定位终极形态:无需设备的人体空间定位技术突破——基于视频空间反演与多摄像机融合的无标签定位体系一、终极问题:定位为什么始终依赖“设备”在传统技术体系中,“定位”几乎等同于“设备”。无论是GPS、UWB、蓝牙还…...
G-Helper解决华硕笔记本风扇异常问题完全指南
G-Helper解决华硕笔记本风扇异常问题完全指南 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar, and other model…...
IPATool终极指南:如何用命令行轻松获取iOS应用安装包?
IPATool终极指南:如何用命令行轻松获取iOS应用安装包? 【免费下载链接】ipatool Command-line tool that allows searching and downloading app packages (known as ipa files) from the iOS App Store 项目地址: https://gitcode.com/GitHub_Trendin…...
