欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > Android >内容正文

Android

android 拦截点击事件,Android事件拦截机制

发布时间:2024/10/14 Android 93 豆豆
生活随笔 收集整理的这篇文章主要介绍了 android 拦截点击事件,Android事件拦截机制 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

一直对事件拦截不是很清楚,读Android群英传的笔记,记录下。

要了解事件拦截,首先要了解触摸事件,触摸事件是捕获触摸屏幕后发生的事件。按一下屏幕通常会有几个事件发生,当按下屏幕,这是事件1。滑动了一下,这是事件2。当手抬起,这是事件3。当重写onTouchEvent方法时,会给我们一个事件封装类MotionEvent。滑动,按下,对应不同的Action(如MotionEvent.ACTION_DOWN,MotionEvent.ACTION_UP),通过对Action的判断就可以实现不同的逻辑了。

咋一看触摸事件好像比较简单,但Android的View是树形结构的,一个View可能放在一个ViewGroup里面,而一个ViewGrop可能又放在另一个ViewGroup里面,可能会存在多层的嵌套结构,那么里面的触摸事件要给谁处理呢?这就要用到事件拦截了。

先附上代码。

MyViewGroupA.java

public class MyViewGroupA extends LinearLayout {

public MyViewGroupA(Context context) {

super(context);

}

public MyViewGroupA(Context context, AttributeSet attrs) {

super(context, attrs);

}

public MyViewGroupA(Context context, AttributeSet attrs,

int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

Log.d("LOG", "ViewGroupA dispatchTouchEvent" + ev.getAction());

return super.dispatchTouchEvent(ev);

}

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

Log.d("LOG", "ViewGroupA onInterceptTouchEvent" + ev.getAction());

return super.onInterceptTouchEvent(ev);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

Log.d("LOG", "ViewGroupA onTouchEvent" + event.getAction());

return super.onTouchEvent(event);

}

}

MyViewGroupB.java

public class MyViewGroupB extends LinearLayout {

public MyViewGroupB(Context context) {

super(context);

}

public MyViewGroupB(Context context, AttributeSet attrs) {

super(context, attrs);

}

public MyViewGroupB(Context context, AttributeSet attrs,

int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public boolean dispatchTouchEvent(MotionEvent ev) {

Log.d("LOG", "ViewGroupB dispatchTouchEvent" + ev.getAction());

return super.dispatchTouchEvent(ev);

}

@Override

public boolean onInterceptTouchEvent(MotionEvent ev) {

Log.d("LOG", "ViewGroupB onInterceptTouchEvent" + ev.getAction());

return super.onInterceptTouchEvent(ev);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

Log.d("LOG", "ViewGroupB onTouchEvent" + event.getAction());

return super.onTouchEvent(event);

}

}

MyView.java

public class MyViewC extends View {

public MyViewC(Context context) {

super(context);

}

public MyViewC(Context context, AttributeSet attrs) {

super(context, attrs);

}

public MyViewC(Context context, AttributeSet attrs,

int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public boolean onTouchEvent(MotionEvent event) {

Log.d("LOG", "View onTouchEvent" + event.getAction());

return super.onTouchEvent(event);

}

@Override

public boolean dispatchTouchEvent(MotionEvent event) {

Log.d("LOG", "View dispatchTouchEvent" + event.getAction());

return super.dispatchTouchEvent(event);

}

}

activity_main.xml

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@android:color/holo_blue_bright">

android:layout_width="300dp"

android:layout_height="300dp"

android:background="@android:color/holo_green_dark">

android:layout_width="150dp"

android:layout_height="150dp"

android:background="@android:color/darker_gray" />

这里有2个ViewGroup,一个View,结构如下

Paste_Image.png

可以看到MyViewGroupA,在最外层,MyViewGroupB在中间,MyViewC在最底层。

ViewGroup分别重写了dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent

View重写了onTouchEvent,dispatchTouchEvent

可以看到ViewGroup比View多了一个方法,看名字是拦截的意思。

当我们点击MyViewC打印log如下

Paste_Image.png

可以看到事件的传递顺序是ViewGroupA -> ViewGroupB - > MyView

事件的处理顺序是MyView - > ViewGroupB - >ViewGroupA

Android对dispatchTouchEvent 的解释如下

/**

* Pass the touch screen motion event down to the target view, or this

* view if it is the target.

*

* @param event The motion event to be dispatched.

* @return True if the event was handled by the view, false otherwise.

**/

dispatchTouchEvent 方法用来传递事件,返回True ,拦截,返回值false不拦截,继续传递。

onTouchEvent也类似,返回True处理,返回False交给上级处理。

可以知道无论是dispatchTouchEvent还是 onTouchEvent,如果返回True,表示这个事件被消费了、处理了不再往下传。

为了了解拦截过程,先忽略dispatchTouchEvent与onTouchEvent方法,简单修改ViewGroupB onInterceptTouchEvent为true,同样点击MyViewC,log如下

Paste_Image.png

可以看到ViewGroupB拦截后,果然MyView就没有事件继续传递了,事件被ViewGroupB自己完成。

总结

以上是生活随笔为你收集整理的android 拦截点击事件,Android事件拦截机制的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。