当前位置:网站首页>View 的滑动冲突
View 的滑动冲突
2022-07-27 08:37:00 【wo不理智】
一.冲突类型
滑动冲突分为三种类型,第一类是外部和内部滑动方向不一致,第二类是外部和内部滑动方向一致,第三类是前两种嵌套的模式。
处理这三种类型的规则分为两类,对于第一种类型,我们可以根据滑动方向来处理,符合处理方向的分配给对应的控件;对于2、3种类型,必须根据业务上的区别来处理,某种状态的处理事件分发给对应的控件来处理。
当用户左右滑动时,需要让外部的View拦截点击事件,当用户上下滑动时,需要让内部View拦截点击事件。简单说就是滑动谁谁就拦截。如图,根据滑动过程中起点和终点的坐标就可以得出到底是水平滑动还是竖直滑动。
- 根据滑动路径和水平方向形成的夹角
- 根据水平方向和竖直方向上的距离差
- 根据水平和竖直方向的速度差
二.解决方法
1.外部拦截法
所谓外部拦截法是指点击事件都要先经过父容器的拦截处理,如果父容器需要此事件就拦截,不需要就不拦截,这种方法比较符合点击事件的分发机制。外部拦截法需要重写父容器的onInterceptTouchEvent方法,在内部做相应的拦截即可,伪代码如下:
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = false;
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
intercepted = false;
break;
case MotionEvent.ACTION_MOVE:
if(父控件需要当前点击事件){
intercepted = true;
} else{
intercepted = false;
}
break;
case MotionEvent.ACTION_UP:
intercepted = false;
break;
}
return intercepted;
}
针对不同的滑动冲突,只需要修改父容器需要当前点击事件这个条件即可。
在onInterceptTouchEvent方法中,首先是ACTION_DOWN这个事件,父容器必须返回false,即不拦截ACTION_DOWN事件,这是因为父容器一旦拦截该事件,那么后续的ACTION_MOVE和ACTION_UP事件都会直接交由父容器处理,事件就无法传递给子元素了;接下来是ACTION_MOVE事件,这个事件可以根据需要来决定是否拦截,如果父容器需要拦截就返回true,反之不拦截就返回false;最后是ACTION_UP事件,这里必须返回false,因为ACTION_UP事件本身没有太多意义。
2.内部拦截法
内部拦截法是指父容器不拦截任何事件,所有的事件都传递给子元素,如果子元素需要此事件就消耗掉,反之就交由父容器处理,这种方法和事件分发机制不一致,需要配合requestDisallowInterceptTouchEvent方法才能正常工作,使用起来较外部拦截法稍显复杂。伪代码如下:
子元素:
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if(父控件需要此点击事件){
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
break;
}
return super.dispatchTouchEvent(event);
}
针对不同的滑动冲突,只需要修改父容器需要当前点击事件这个条件即可。
除了子元素需要做处理以外,父元素也要默认拦截除了ACTION_DOWN以外的其他事件,这样当子元素调用getParent().requestDisallowInterceptTouchEvent(true)方法时,父容器才能继续拦截所需的事件。
父元素:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
if(action == MotionEvent.ACTION_DOWN){
return false;
} else {
return true;
}
}
边栏推荐
- Pass parameters and returned responses of flask
- After installing mysql, docker entered the container and found that he could not log in to MySQL
- Minio 安装与使用
- Flutter 渲染机制——GPU线程渲染
- 带宽 与 货币
- List delete collection elements
- 1176 questions of Olympiad in informatics -- who ranked K in the exam
- Openresty + keepalived to achieve load balancing + IPv6 verification
- [geek challenge 2019] finalsql 1
- Use of elastic box / expansion box (Flex)
猜你喜欢
随机推荐
JS advanced knowledge - function
containerd拉取私库镜像失败(kubelet)
Using ecological power, opengauss breaks through the performance bottleneck
如何卸载--奇安信安全终端管理系统
All in one 1319 - queue for water
Function realization of order system
Idea remote debugging
Vcenter7.0 managing esxi7.0 hosts
Zhongang Mining: the new energy industry is developing rapidly, and fluorine chemical products have a strong momentum
[NPUCTF2020]ReadlezPHP 1
Background image related applications - full, adaptive
众昂矿业:新能源行业快速发展,氟化工产品势头强劲
Software test interview questions (key points)
Connection failed during installation of ros2 [ip: 91.189.91.39 80]
Set set
Query and association of flask to database
Graph node deployment and testing
百人参与,openGauss开源社区这群人都在讨论什么?
QPushButton 按钮的创建与简单应用
Alibaba cloud international receipt message introduction and configuration process





![[NPUCTF2020]ReadlezPHP 1](/img/d9/590446b45f917be3f077a9ea739c20.png)




