View内容滑动概念 scrollTo scrollBy
- scrollTo(x,y) x,y 是绝对值,如果x,y不变,重复调用是不会移动的。
- scrollBy(x,y) x,y是增量之,每次调用都会在mScrollX,mScrollY的基础上不断叠加数值。
mScrollX,mScrollY 请参见 【Android View基础】View中几个容易混淆的距离及坐标量
scroll移动的是View的“内容”,而非整个view,移动的区域范围只限于view的边界内,内容超出部分不可见。listView是个典型。
滑动冲突的场景及如何应对?
先来看四种场景:
场景A
这是最普通没有滑动冲突的场景。
View监听滑动事件,并且根据move事件来scroll View的内容,内容位置随之上下移动。
一切安好。
场景B:遭遇
在move过程中,事件先交给容器outer,outer自身有横向的滑动需求,比如说ViewPager,然后outer的child view:inner 有纵向的滑动需求,比如说listView.
解决思路:
其实解决的关键在于outer,在outer在拿到事件分配权后,需要辨识哪些应该自己拦截处理,哪些应该交给child view处理,那么这里就需要有一套判断逻辑了。
在场景B中,其实逻辑还蛮明显的。outer处理横向滑动,inner处理纵向滑动,所以判断的关键就是区分move事件是横向还是纵向滑动。
判断的方法:
坐标差值比较法
在move过程中,比较y和x的坐标差值
dy > dx 垂直滑动事件
dy < dx 水平滑动事件
速度比较法
Vx < Vy 垂直滑动事件
Vx > Vy 水平滑动事件
场景C
outer 和 inner 都有纵向的滑动事件的处理需求,这可谓真正的滑动冲突啊
这需要具体业务需求来支撑该逻辑判断。比如inner view内部滑动滑到顶了,这样就由outer来处理滑动。这个时候
场景D
比较复杂,但是万事不其宗,有一点,父容器有决定事件的分配权,在只有1,2的场景下,1只需处理横纵的事件拦截判断,而增加了3后,判断逻辑还得加上对3的事件分发判断上。作为1最顶层的父容器需要考虑子孙的所有滑动事件需求,权利越大,责任也就越大!
虽然有这么多层,需要逐层化解,分解到都变成场景B,C的情况,就好办了。
- 1 vs 2 , 1 vs 3 ——> 编写1的事件拦截逻辑
- 2 vs 3 —–>编写2的事件拦截逻辑