ListView 5种滑动模式解析全在这里了


这篇文章已同步到 ListView 5种滑动模式解析全在这里了,提供更好的阅读体验


前段时间在使用 ListView 的过程中,需要对一个子 Item 优化横向 Bannar 的滑动体验,于是借此机会,深入了解了一下 ListView 滑动的一些知识,来探究一下,一个 View 滑动,究竟需要做哪些事情。

滑动模式基本介绍

ListView 的滑动模式使用变量 mTouchMode 来表示,分为以下几种模式:

mTouchMode 注释 解析 备注
TOUCH_MODE_REST Indicates that we are not in the middle of a touch gesture 标识当前未处于滑动手势中 用于重置当前滑动状态
TOUCH_MODE_DOWN Indicates we just received the touch event and we are waiting to see if the it is a tap or a scroll gesture 标识仅仅是接到了触摸事件,还需要进一步判断是点按事件还是滑动手势
TOUCH_MODE_TAP Indicates the touch has been recognized as a tap and we are now waiting to see if the touch is a longpress 标识触摸事件已经被识别为点按事件,还需要进一步判断是不是长按事件
TOUCH_MODE_DONE_WAITING Indicates we have waited for everything we can wait for, but the user’s finger is still down 标识我们已经等了很久,但是用户的手势还是处于down状态
TOUCH_MODE_SCROLL Indicates the touch gesture is a scroll 标识触摸手势是滑动事件
TOUCH_MODE_FLING Indicates the view is in the process of being flung 标识当前View是在“甩”的过程中
TOUCH_MODE_OVERSCROLL Indicates the touch gesture is an overscroll - a scroll beyond the beginning or end. 标识手势是一个越界滑动越界滑动是指滑动超出了内容区域的首尾 这种状态下,AbsListView 会在 DOWN 事件时拦掉事件,交给自己的 onTouchEvent 处理,事件不会继续往子 View 传递
TOUCH_MODE_OVERFLING Indicates the view is being flung outside of normal content bounds and will spring back. 标识当前View被“甩”出了正常滑动区域,即将会弹回来 这种状态下,AbsListView 会在 DOWN 事件时拦掉事件,交给自己的 onTouchEvent 处理,事件不会继续往子 View 传递

ListView 滑动模式有这么多,其实都是基于控件自身设计和交互上的考虑。我们会发现上表中出现的滑动模式,前四个模式,标识 ListView 当前处于的状态,并没有”滑“起来,而后四个模式,却在实际中有对应的场景:

  • TOUCH_MODE_SCROLL:最简单的场景,对应于 ListView 跟随我们的手指上下滑动
  • TOUCH_MODE_FLING:列表太长时,我们想要快速浏览,手指快速向下(上)滑动,手机离开屏幕伴有一定的加速度
  • TOUCH_MODE_OVERSCROLL:手机滑动列表已经超出内容的可滑动区域后,还继续滑动,表示 ListView 没有更多的内容了
  • TOUCH_MODE_OVERFLING:Fling 之后,滑动还没停下来的时候超出内容的滑动区域,继续滑动的状态,原生默认的效果是波纹动画,也是标示 ListView 没有更多可以滑动的内容了
  • FAST_SCROLL:除了以上的模式之外,还有一个模式 ,对应的场景是,我们拖动滑动标识器(scroll thumb)快速定位到 ListView 的某个位置,FAST_SCROLL 模式的事件处理在整个以上模式的最前边,是独立于这些模式的,我们后边单独分析

以上就是我们这次要讲得 5 种滑动模式

这里有个模式变化表,仅供参考,单次滑动屏幕,(中间不抬手指)

模式变化 说明
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_OVERSCROLL (不可能,无法直接从 DOWN->OVERSCROLL,因为 mScrollY 必须经过 onOverScrolled 之后才能有值)
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> 按下,长按,TAP 普通点击,长按
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_SCROLL -> TOUCH_MODE_REST 普通的滑动模式
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_SCROLL -> TOUCH_MODE_OVERSCROLL-> TOUCH_MODE_OVERFLING -> TOUCH_MODE_FLING -> TOUCH_MODE_REST 初始化 -> 触摸屏幕 -> 接触滑动 -> 越界 -> 越界FLING -> FLING -> 重置
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_SCROLL -> TOUCH_MODE_OVERSCROLL -> TOUCH_MODE_REST 初始化 -> 触摸屏幕 -> 接触滑动 -> 越界 -> 松手 -> 弹回重置
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_SCROLL -> TOUCH_MODE_OVERSCROLL -> TOUCH_MODE_SCROLL -> TOUCH_MODE_REST 初始化 -> 触摸屏幕 -> 接触滑动 -> 越界 -> 往回滑动 -> 松手
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_FLING (不可能,无法直接从 DOWN->FLING,因为 fling 需要加速度,必须要经过 move)
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_SCROLL -> TOUCH_MODE_FLING -> TOUCH_MODE_OVERFLING -> TOUCH_MODE_REST 初始化 -> 触摸屏幕 -> 接触滑动 -> 松手FLING -> 越界FLING -> 停止
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_SCROLL -> TOUCH_MODE_FLING -> TOUCH_MODE_OVERFLING -> TOUCH_MODE_FLING -> TOUCH_MODE_REST 初始化 -> 触摸屏幕 -> 接触滑动 -> 松手FLING -> 越界FLING -> FLING -> 停止
TOUCH_MODE_REST -> TOUCH_MODE_DOWN -> TOUCH_MODE_SCROLL -> TOUCH_MODE_FLING -> TOUCH_MODE_REST 初始化 -> 触摸屏幕 -> 接触滑动 -> FLING -> 到达边缘(当前 overScrollMode 被禁用)

从哪里开始

滑动是与用户连接非常密切的交互方式,而感知用户屏幕行为最重要的一个途径就是 MotionEvent 事件,所以要了解 ListView 的滑动模式,我们首先就需要把目光放到 ListView 处理屏幕触摸事件的两个方法

android.widget.AbsListView#onInterceptTouchEvent()
android.widget.AbsListView#onTouchEvent()

ListView 继承自 ViewGroup,所以事件分发的过程会经历以下三个方法(并不是每次事件流都必走,顺序也不是从上到下的)

android.view.ViewGroup#dispatchTouchEvent()
android.widget.AbsListView#onInterceptTouchEvent</
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值