温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

View(2) - 事件分发

发布时间:2020-07-23 11:02:54 来源:网络 阅读:64 作者:lm8751 栏目:移动开发

一、体系

Activity -> phoneWindow ->DecorView -> ViewGroup

1.DecorView包含StateViewTitileViewContentView 等子View ,setContentView 设置的是DecorViewView

2.Activity 托管 phonwWindow实例对象,phoneWindow管理DecorView。因此在Activity中可以getWindow().DecorView得到顶层View

3.decorView  https://blog.csdn.net/guxiao1201/article/details/41744107


二、类型

1.ACTION_DOWN:手指刚接触屏幕,按下去的那一瞬间产生该事件

2.ACTION_MOVE:手指在屏幕上移动时候产生该事件

3.ACTION_UP:手指从屏幕上松开的瞬间产生该事件

4.ACTION_CANCLE : 手指从当前控件移动到控件外


正常情况下,呈现在MotionEvent上来讲分为3
1.点击后抬起,也就是单击操作:ACTION_DOWN -> ACTION_UP
2.点击后再风骚的滑动一段距离,再抬起:ACTION_DOWN -> ACTION_MOVE -> ... -> ACTION_MOVE -> ACTION_UP

3.MotionEvent.ACTION_CANCEL滑动问题解决

https://blog.csdn.net/kingofhacker/article/details/75111372


三、原理

1.dispatchTouchEvent(MotionEvent event) 事件分发 返回true 表示此事件已消费

2.onInterceptTouchEvent(MotionEvent ev) 事件拦截 返回true 表示此事件需拦截

3. onTouchEvent(MotionEvent ev) 事件处理 返回true 表示此事件已消费


备注:

1.viewGroup首先会执行dispatchTouchEventdispatchTouchEvent调用onInterceptTouchEvent

如果返回true,则交由自己的onTouchEvent处理。返回false,交由子viewdispatchTouchEvent处理,一直递归下去。如果到最底层view onTouchEvent还是false,则事件开始交给该view的父view onTouchEvent解决。如果没有view处理,最后交由Activity  onTouchEvent解决。

2.View类没有onInterceptTouchEvent()。如果子ViewView,DispatchTouchEvent()会直接调用onTouchEvent()处理。

3.View可以通过requestDisallowInterceptTouchEvent方法干预父View的事件分发过程(ACTION_DOWN事件除外)。

4.方法执行顺序  onTouch -> onTouchEvent -> onClickListener . 如前面方法返回true 后面方法收不到事件,onClickListener是在onTouchEvent中被调用的。

5.ViewonTouchEvent方法默认都会消费掉事件(返回true),除非它是不可点击的(clickablelongClickable都是false),ViewlongClickable默认为falseclickable需要区分情况,如Buttonclickable默认为true,而TextViewclickable默认为false

参考:https://www.jianshu.com/p/238d1b753e64



四、事件冲突

种类

1.内外层滑动方向不一致,外层ViewGroup是可以横向滑动的,内层View是可以竖向滑动的,例如外层是ViewPager,内层是ListView

2.内外层滑动方向一致,外层ViewGroup是可以竖向滑动的,内层View同样也是竖向滑动的,例如ScrollView包裹ListView

解决

  1.外部拦截法  在父View onInterceptTouchEvent 判断事件交由谁处理

        2.内部拦截法  在父View onInterceptTouchEvent() Action_Down事件不拦截。

      在子View dispatchTouchEvent 根据业务判断是否交由父类处理parent.requestDisallowInterceptTouchEvent(false);

参考:https://www.jianshu.com/p/982a83271327

判断触摸点是否在view的区域:https://blog.csdn.net/u013651026/article/details/80446541




向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI