Android 下拉刷新实践

article/2025/10/26 18:01:55

1. 手动实现一个下拉刷新功能。

2. 效果图:

3. view结构

 4.实现思路

<com.luocc.tim.recycler.RefreshLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/refresh"android:layout_width="match_parent"android:layout_height="50dp"android:layout_marginTop="-50dp"android:gravity="bottom|center" /><com.luocc.tim.recycler.ChatListRecyclerandroid:id="@+id/chat_list"android:layout_width="match_parent"android:layout_height="wrap_content" />
</com.luocc.tim.recycler.RefreshLayout>

给refresh部分设置负的margin,让他显示在布局外面,平常时这个view是看不见的,当下拉的时候通过scrollBy/scrollTo方法滑动,松手后让他完全隐藏或者显示一个合适的高度。

5.实现要点

5.1何时滑动

本功能实现的基础是View的事件的分发、拦截、处理。

继承一个ViewGroup,按需要重写touch相关方法:

// 分发事件
public boolean dispatchTouchEvent(MotionEvent ev)// 拦截事件
public boolean onInterceptTouchEvent(MotionEvent ev)// 处理事件
public boolean onTouchEvent(MotionEvent event)

我对这几个方法的了解仅仅是看过一些博客,简单解释一下:

手指触摸手机屏幕,产生DOWN事件,由最外层(父View)ViewGroup的dispatchTouchEvent方法分发,到onInterceptTouchEvent,如果该方法返回true,说明本ViewGroup需要处理这个事件,下一步执行onTouchEvent;如果返回false,说明本ViewGroup不对这个事件做处理,让这个事件继续向下流转,然后重复父ViewGroup的操作,直到某个View.

一次事件一般是这样的:

ACTION_DOWN -> ACTION_MOVE .... 无数个ACTION_MOVE -> ACTION_UP

实现下拉功能需要做的就是,在满足下拉条件时,让RecyclerView的父View的onInterceptEvent方法返回true,拦截此事件,这样事件就走不到RecyclerView;不满足条件时就让事件走到RecyclerView,让其顺利滑动。

public boolean onInterceptTouchEvent(MotionEvent ev) {Log.d(TAG, "onInterceptTouchEvent: action = " + ev.getAction());switch (ev.getAction()) {......case MotionEvent.ACTION_MOVE:// 是否是向下滑动boolean moveDown = ev.getY() - mLastY > 0;Log.d(TAG, "onInterceptTouchEvent: moveDown ? " + moveDown);// 该方法判断RecyclerView是否滑动到最顶部了if (moveDown && !chatList.canScrollVertically(-1)) {return true;}break;......}return super.onInterceptTouchEvent(ev);
}

5.2 滑动冲突

当DOWN事件被某一层VIewGroup拦截后,后续的MOVE、UP事件都会直接走到它的onTouchEvent方法中,不会经过onInterceptTouchEvent,这就会产生一些问题。

当RefreshLayout(RecyclerView的父View)拦截了事件,正在处理下拉操作时,刷新区域出现,这很正常,但是这时候向上滑动会发现刷新区域已经完全闭合了,RecyclerView的滑动却不起作用。

当然,你也可以这种现象当做一个特性,但我很无聊,所以我决定把他修一下。

类似的还有,当RecyclerView在滑动的时候,滑动到最顶部继续下拉,刷新区域出不来。这是因为滑动事件被RecyclerView拦截后,后续的事件都走到他这了,导致RefreshLayout收不到滑动事件。

解决第一点的做法是,在明确知道RefreshLayout不需要处理后续MOVE事件后,手动发送一个DOWN事件。

public boolean dispatchTouchEvent(MotionEvent ev) {Log.d(TAG, "dispatchTouchEvent: action = " + ev.getAction());switch (ev.getAction()) {case MotionEvent.ACTION_MOVE:if (mChildMove) {dispatchTouchEvent(// MetaState参数不清楚干啥用的,我就随便传了一个MotionEvent.obtain(SystemClock.uptimeMillis(),SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,ev.getX(),ev.getY(),ev.getMetaState()));return false;}break;case MotionEvent.ACTION_UP:break;}return super.dispatchTouchEvent(ev);
}

在某个View在处理事件时,后续的MOVE都往他这里跑,原因是ViewGroup里有个链表

private TouchTarget mFirstTouchTarget;// Handle an initial down.
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.cancelAndClearTouchTargets(ev);resetTouchState();
}

他会记住当前正在处理事件的View,而重新发送一个DOWN事件会重置它(不知道有没有更好的办法),重置后onInterceptTouchEvent就能重新工作了。

解决第二点的做法是,子View不想处理事件了,想让父View继续拦截事件。

// 在onTouchEvent中判断
if (!canScrollVertically(-1)) {getParent().requestDisallowInterceptTouchEvent(false);
}

该方法让父View重新拦截。

6. 总结

实现下拉刷新最关键的地方在于理解View事件的流转机制,分发、拦截、处理。

最后附上代码:gitee地址


http://chatgpt.dhexx.cn/article/EeRFnBfp.shtml

相关文章

【uniapp】页面下拉刷新

目录 一、全局 二、局部 1、一个页面一个下拉刷新 2、一个页面多个下拉刷新&#xff08;切换时滚动条回到顶部&#xff09; 3、一个页面多个下拉刷新&#xff08;切换时恢复滚动条位置&#xff09; 一、全局 修改pages.json的"enablePullDownRefresh": true, …

uniapp 下拉刷新

uniapp 下拉刷新&#xff08;全局&单页面&#xff09; 全局设置 在pages.json文件的globalStyle对象中开启enablePullDownRefresh属性 单页面 在pages.json文件中的pages数组中找到对应的页面&#xff0c;在对应页面的style属性中开启enablePullDownRefresh属性 下拉刷…

Android 下拉刷新框架实现

前段时间项目中用到了下拉刷新功能&#xff0c;之前在网上也找到过类似的demo&#xff0c;但这些demo的质量参差不齐&#xff0c;用户体验也不好&#xff0c;接口设计也不行。最张没办法&#xff0c;终于忍不了了&#xff0c;自己就写了一个下拉刷新的框架&#xff0c;这个框架…

Android中实现下拉刷新

需求&#xff1a;项目中的消息列表界面要求实现类似sina微博的下拉刷新&#xff1b; 思路&#xff1a;一般的消息列表为ListView类型&#xff0c;将list加载到adapter中&#xff0c;再将adapter加载到ListView中&#xff0c;从而实现消息列表的展示。而下拉刷新要求给消息列表…

微信小程序下拉刷新

一、如何设置微信小程序所有页面都可以下拉刷新呢&#xff1f; 1、在app.json的"window"中进行配置 &#xff08;1&#xff09;把"backgroundTextStyle":“light"改为"backgroundTextStyle”:“dark” &#xff08;2&#xff09;添加"enab…

下拉刷新上拉加载

目录 原理实现效果 原理 想必使用过微信开发工具的应该都接触过上拉加载下拉刷新配置。 原理呢就是通过根据当前刚开始触碰的屏幕垂直y轴距离和滑动时所触碰垂直y轴距离&#xff0c;从而来判断是上拉&#xff0c;下拉。 实现 使用的vue2 封装的组件&#xff0c;js大致思路是…

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

转载请注明出处&#xff1a;http://blog.csdn.net/guolin_blog/article/details/9255575 最近项目中需要用到ListView下拉刷新的功能&#xff0c;一开始想图省事&#xff0c;在网上直接找一个现成的&#xff0c;可是尝试了网上多个版本的下拉刷新之后发现效果都不怎么理想。有些…

【Demo】教你实现下拉刷新

前言 第三方库很常见&#xff0c;我们开发需求的时候经常会用到下拉刷新组件&#xff0c;如果要我们自己实现下拉刷新该如何实现尼&#xff1f; 效果 实现原理 1、监听 touchstart事件记录初始startY 2、监听 touchmove事件 e.touches[0].pageY - startY得到 deltaY&#xf…

如何实现上拉加载,下拉刷新

答&#xff1a;下拉刷新和上拉加载这两种交互⽅式通常出现在移动端中 本质上等同于PC⽹⻚中的分⻚&#xff0c;只是交互形式不同 开源社区也有很多优秀的解决⽅案&#xff0c;如 iscroll 、 better-scroll 、 pulltorefresh.js 库等等 这些第三⽅库使⽤起来⾮常便捷 我们通…

jira使用教程管理项目

添加工作流 1.点击项目设置 2.点击工作流&#xff0c;然后点击切换方案 3.进入切换方案界面之后&#xff0c;点击工作流&#xff0c;然后点击添加工作流 4.输入工作流名称&#xff0c;点击添加 5.编辑工作流 可以导出工作流供别人使用 编辑之前添加的工作流 提交bug

今日记录:JIRA使用指南

JIRA流程与使用指南 学习总结&#xff1a; 什么是JIRA&#xff1f;为什么要用任务管理工具&#xff1f;JIRA基础流程 ① 什么是JIRA&#xff1f; JIRA是一个项目与事务管理工具&#xff0c;被广泛应用于缺陷跟踪、客户服务、需求收集、流程审批、任务跟踪和敏捷管理等工作领…

JIRA-使用教程_概念

博客概要 JIRA是一个非常强大的项目与事务跟踪工具&#xff0c;博主在具体工作使用中对它爱不释手 &#xff0c;发现它功能全面、配置灵活、扩展丰富…反正优点一大堆&#xff01;好东西嘛就要拿出来&#xff0c;大家一起分享~本博文先简单介绍JIRA相关的基本信息。 文章目录 博…

Confluence+Jira使用

Jira过滤器的使用方式&#xff1a; project MCU AND issuetype 测试用例 AND component GPIO ORDER BY summary ASC实例&#xff1a;

jira使用教程 一(从官方文档理解)

JIRA官方说明 JIRA使用教程 blog QA: jira 如何关联到Gerrit Reviews JIRA Concepts - Issues Aim JIRA tracks issues, which can be bugs, feature requests, or any other tasks you want to track. JIRA可以跟踪问题&#xff0c;可以是bug、特性请求或任何其他你想跟踪…

JIRA-使用教程_问题单-新建

博客概要 简单分享新增并查看一个问题单的步骤~ 文章目录 博客概要《JIRA-使用教程》_总目录问题单-新建1.进入项目2.新建唤起3.填写新建弹窗4.查看问题 总结 《JIRA-使用教程》_总目录 文章超链接&#xff1a;https://blog.csdn.net/qq_41386332/article/details/108865809 …

项目管理工具——Jira使用和配置

摘要 链接&#xff1a;https://pan.baidu.com/s/1_PgOuOWsS1lnHIIyI0y4pA 提取码&#xff1a;v0dy 本博文将介绍在软件开发中的常用的软件管理工具。Jira是Atlassian公司出品的一款事务管理软件&#xff08;缺陷管理类的软件&#xff09;。无论是“需求”&#xff0c;还是“…

命令进入mysql创建jira_JIRA使用教程:连接数据库—MySQL_MySQL

本文主要介绍如何连接JIRA到mysql数据库。 首先 查看MySQL的版本是否支持&#xff0c;查阅 支持的平台 。 如果是转移JIRA到另一台服务器&#xff0c;先导出数据为XML备份&#xff0c;然后将旧数据库中的数据传输到新的数据库。 如果你打算用同一个MySQL服务器安装Confluence和…

jira oracle安装,JIRA使用教程:连接数据库—Oracle

本文主要介绍连接JIRA到Oracle数据库。 首先 检查Oracle的版本是否支持&#xff0c;详见支持的平台。 如果是转移JIRA到另一台服务器&#xff0c;先导出数据为XML备份&#xff0c;然后将旧数据库中的数据传输到新的数据库。 在开始前关闭JIRA&#xff0c;除非你正在运行Setup W…

命令进入mysql创建jira_JIRA使用教程:连接数据库―MySQL

本文主要介绍如何连接JIRA到mysql数据库。 首先 查看MySQL的版本是否支持&#xff0c;查阅 支持的平台 。 如果是转移JIRA到另一台服务器&#xff0c;先导出数据为XML备份&#xff0c;然后将旧数据库中的数据传输到新的数据库。 如果你打算用同一个MySQL服务器安装Confluence和…

Jira使用浅谈篇一

&#x1f680; 优质资源分享 &#x1f680; 学习路线指引&#xff08;点击解锁&#xff09;知识定位人群定位&#x1f9e1; Python实战微信订餐小程序 &#x1f9e1;进阶级本课程是python flask微信小程序的完美结合&#xff0c;从项目搭建到腾讯云部署上线&#xff0c;打造一…