view 事件分发机制

来源:互联网 发布:淘宝免费模块代码 编辑:程序博客网 时间:2024/04/30 08:29

View事件分发机制,其实就是我们对屏幕操作触发view那一刻开始,而我们手机上响应我们各种操作事件的就是各种各样的视图组件也就是View,在Android中,所有的视图都继承于View,另外通过各种布局组件(ViewGroup)来对View进行布局,ViewGroup也继承于View。所有的UI控件都是继承于View,而所有的布局控件、容器控件都是继承于ViewGroup。所以,我们的事件操作主要就是发生在View和ViewGroup之间。

1.我们在屏幕上对view的各种操作,组成了Android的事件响应。总的来说,所有的事件都由如下三个部分作为基础:按下(ACTION_DOWN) 移动(ACTION_MOVE) 抬起(ACTION_UP)

 view.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View view, MotionEvent motionEvent) {                switch (motionEvent.getAction()) {                    case MotionEvent.ACTION_DOWN:                        LogUtil.d("ACTION_DOWN");                        break;                    case MotionEvent.ACTION_MOVE:                        LogUtil.d("ACTION_MOVE");                        break;                    case MotionEvent.ACTION_UP:                        LogUtil.d("ACTION_UP");                        break;                }                return false;            }        });

2.所谓点击事件的事件分发,就是当一个MotionEvent产生了以后,系统需要把这个事件传递给一个具体的View(ViewGroup也继承于View),这个传递的过程就叫做分发过程,这个点击事件的分发过程需要三个很重要的方法来共同完成:disPatchTouchEvent、onInterceptTouchEvent、和onTouchEvent。

public boolean disPatchTouchEvent(MotionEvent ev)
用来进行事件的分发,如果事件能够传递给当前的View,那么此方法一定会被调用,Android中所有的点击事件都必须经过这个方法的分发,然后决定是自身消费当前事件还是继续往下分发给子控件处理。返回true表示不继续分发,事件没有被消费,返回false则继续往下分发,如果是ViewGroup则分发给onInterceptTouchEvent进行判断是否拦截该事件,这个方法的返回结果受到当前View的onTouchEvent和下级View的disPatchTouchEvent方法的影响,返回结果表示是否消耗当前事件。

public boolean onTouchEvent(MotionEvent ev)
在diaPatchTouchEvent方法中调用,用来处理点击事件,返回结果表示是否消耗当前事件,如果不消耗,则在同一个事件序列当中,当前View无法再次接收到事件。

public boolean onInterceptTouchEvent(MotionEvent ev)
是ViewGroup中才有的方法,View中没有,它的作用是负责事件的拦截,返回true的时候表示拦截当前事件,不继续往下分发,交给自身的onTouchEvent进行处理。返回false则不拦截,继续往下传。这是ViewGroup特有的方法,因为ViewGroup中可能还有子View,而在Android中View中是不能再包含子View的(IOS可以),在上述方法内部被调用,如果当前View拦截了某个事件,那么同一个事件序列中(指从手指接触屏幕的那一刻起,到手指离开屏幕的那一刻结束,中间含有不定的ACTION_MOVE事件,最终以ACTION_UP事件结束)此方法不会被再次调用,返回结果表示是否拦截当前事件。
这三个方法可以用如下伪代码表示:

public boolean disPathchTouchEvent(MotionEvent ev){
//consume指代点击事件是否被消耗
boolean consume=false;
//表示当前父布局要拦截该事件
if(onInterceptTouchEvent(MotionEvent ev)){
consume=onTouchEvent(ev);
}else{
//传递给子元素去处理
child.disPatchTouchEvent(ev);
}
return consume;
}

0 0
原创粉丝点击