1.Activity事件处理
package com.example.eventdemo01;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "xtm";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
DebugUtils.printLogD(TAG,"Activity dispatchTouchEvent.");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
DebugUtils.printLogD(TAG,"Activity onTouchEvent.");
return super.onTouchEvent(event);
}
}
按下:会回调一次dispatchTouchEvent,onTouchEvent
移动:多次回调dispatchTouchEvent,onTouchEvent
抬起:会回调一次dispatchTouchEvent,onTouchEvent
相关日志:
// 按下
2020-12-28 09:51:49.210 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:49.210 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
// 移动
2020-12-28 09:51:49.848 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:49.848 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 09:51:49.865 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:49.865 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 09:51:49.881 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:49.881 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 09:51:49.897 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:49.898 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 09:51:49.915 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:49.915 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 09:51:49.932 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:49.932 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 09:51:49.948 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:49.948 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
// 抬起
2020-12-28 09:51:50.962 17300-17300/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 09:51:50.962 17300-17300/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2.ViewGroup事件处理
自定义一个ViewGroup
package com.example.eventdemo01;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;
public class MyViewGroup extends LinearLayout {
private static final String TAG = "xtm";
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
DebugUtils.printLogD(TAG,"MyViewGroup dispatchTouchEvent.");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
DebugUtils.printLogD(TAG,"MyViewGroup onInterceptTouchEvent.");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean isConsume = super.onTouchEvent(ev);
DebugUtils.printLogD(TAG,"MyViewGroup onTouchEvent. isConsume:"+isConsume);
return isConsume;
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<com.example.eventdemo01.MyViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</com.example.eventdemo01.MyViewGroup>
点击一次的打印:
// 按下
2020-12-28 14:25:33.741 7326-7326/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:25:33.741 7326-7326/com.example.eventdemo01 D/xtm: MyViewGroup dispatchTouchEvent.
2020-12-28 14:25:33.741 7326-7326/com.example.eventdemo01 D/xtm: MyViewGroup onInterceptTouchEvent.
2020-12-28 14:25:33.741 7326-7326/com.example.eventdemo01 D/xtm: MyViewGroup onTouchEvent. isConsume:false
2020-12-28 14:25:33.741 7326-7326/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
// 移动
2020-12-28 14:25:34.948 7326-7326/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:25:34.948 7326-7326/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 14:25:34.963 7326-7326/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:25:34.963 7326-7326/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 14:25:34.980 7326-7326/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:25:34.980 7326-7326/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 14:25:35.097 7326-7326/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:25:35.097 7326-7326/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
// 抬起
2020-12-28 14:25:36.269 7326-7326/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:25:36.269 7326-7326/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
3.View事件处理
父亲布局:
package com.example.eventdemo01;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;
public class MyViewGroup extends LinearLayout {
private static final String TAG = "xtm";
public MyViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
DebugUtils.printLogD(TAG,"MyViewGroup dispatchTouchEvent.");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
DebugUtils.printLogD(TAG,"MyViewGroup onInterceptTouchEvent.");
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean isConsume = super.onTouchEvent(ev);
DebugUtils.printLogD(TAG,"MyViewGroup onTouchEvent. isConsume:"+isConsume);
return isConsume;
}
}
子布局
package com.example.eventdemo01;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class MyLinearLayout extends LinearLayout {
private static final String TAG = "xtm";
public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
DebugUtils.printLogD(TAG,"MyLinearLayout dispatchTouchEvent.");
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
DebugUtils.printLogD(TAG,"MyLinearLayout onInterceptTouchEvent.");
return false;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean isConsume = super.onTouchEvent(ev);
DebugUtils.printLogD(TAG,"MyLinearLayout onTouchEvent. isConsume:"+isConsume);
return isConsume;
}
}
子布局嵌套一个View
package com.example.eventdemo01;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
public class MyImageView extends AppCompatImageView {
private static final String TAG = "xtm";
public MyImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
DebugUtils.printLogD(TAG,"MyImageView dispatchTouchEvent.");
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean isConsume = super.onTouchEvent(event);
DebugUtils.printLogD(TAG,"MyImageView onTouchEvent. isConsume:"+isConsume);
return isConsume;
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<com.example.eventdemo01.MyViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.example.eventdemo01.MyLinearLayout
android:background="#00BCD4"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.eventdemo01.MyImageView
android:layout_gravity="center"
android:background="#f0f"
android:layout_width="300dp"
android:layout_height="300dp"/>
</com.example.eventdemo01.MyLinearLayout>
</com.example.eventdemo01.MyViewGroup>
按下抬起后打印:
// 按下
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: MyViewGroup dispatchTouchEvent.
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: MyViewGroup onInterceptTouchEvent.
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: MyLinearLayout dispatchTouchEvent.
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: MyLinearLayout onInterceptTouchEvent.
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: MyImageView dispatchTouchEvent.
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: MyImageView onTouchEvent. isConsume:false
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: MyLinearLayout onTouchEvent. isConsume:false
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: MyViewGroup onTouchEvent. isConsume:false
2020-12-28 14:28:49.661 8586-8586/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
// 移动
2020-12-28 14:28:50.546 8586-8586/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:28:50.546 8586-8586/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 14:28:50.563 8586-8586/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:28:50.563 8586-8586/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
2020-12-28 14:28:50.580 8586-8586/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:28:50.580 8586-8586/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
// 抬起
2020-12-28 14:28:51.229 8586-8586/com.example.eventdemo01 D/xtm: Activity dispatchTouchEvent.
2020-12-28 14:28:51.229 8586-8586/com.example.eventdemo01 D/xtm: Activity onTouchEvent.
观察设置MyLinearLayout的onInterceptTouchEvent和onTouchEvent的不同返回值的事件传递
按下移动并抬起MyImageView:
onInterceptTouchEvent | onTouchEvent | 按下 | 移动 | 抬起 |
false | false | dispatchTouchEvent:Activity->MyViewGroup->MyLinearLayout->MyImageView onTouchEvent:MyImageView->MyLinearLayout->ViewGroup->Actvity | dispatchTouchEvent: Activity onTouchEvent:Activity | 同移动 |
false | true | dispatchTouchEvent:Activity->MyViewGroup->MyLinearLayout->MyImageView onTouchEvent:MyImageView->MyLinearLayout | dispatchTouchEvent: Activity->MyViewGroup->MyLinearLayout onTouchEvent:MyLinearLayout | 同移动 |
true | false | dispatchTouchEvent:Activity->MyViewGroup->MyLinearLayout onTouchEvent:MyLinearLayout->ViewGroup->Actvity | dispatchTouchEvent: Activity onTouchEvent: Activity | 同移动 |
true | true | dispatchTouchEvent:Activity->MyViewGroup->MyLinearLayout onTouchEvent:MyLinearLayout | dispatchTouchEvent: Activity->MyViewGroup->MyLinearLayout onTouchEvent: MyLinearLayout | 同移动 |
从上表看出:
1.移动事件主要看onTouchEvent的返回值,true表示所有移动事件都在这里处理,不再回传给父布局处理;false表示向父布局找一个返回true的布局,若没有的话就都交给了Activity处理。
2.onInterceptTouchEvent表示事件是否向下传递。
3.onTouchEvent表示事件最终由谁处理。
已获取焦点的子ViewGroup可以通过以下方法拦截事件:
/**
* Called when a child does not want this parent and its ancestors to
* intercept touch events with
* {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}.
*
* <p>This parent should pass this call onto its parents. This parent must obey
* this request for the duration of the touch (that is, only clear the flag
* after this parent has received an up or a cancel.</p>
*
* @param disallowIntercept True if the child does not want the parent to
* intercept touch events.
*/
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept);