事件分发机制之-Button的onTouch()事件分析

##基础知识:
1.本篇文章就不分析晦涩难懂的源码了(加上源码后文章内容太长,建议有耐心的读者自己查看源码来验证文章的分析结果)。在这里通过简单的代码直接打印日志让你清晰的认识Button的OnTouch事件传递机制(和onClick,onLongClick事件发生先后顺序)。
2.在onTouch事件中:down事件返回值标记此次事件是否为点击事件(返回false,是点击事件;返回true,不记为点击事件),而up事件标记此次事件结束时间,也就是判断是否为长按。

####一 . onTouch返回false

1.首先是onTouch事件的down事件发生,此时,如果长按,触发onLongClick事件;
2.然后是onTouch事件的up事件发生,up完毕,最后触发onClick事件。

日志:
不长按.png

长按.png

####二 . onTouch返回true

1.首先是onTouch事件的down事件发生,然后是onTouch事件的up事件发生;
2.期间不触发onClick和onLongClick事件

日志:
不长按.png

长按.png

####三 . onTouch:down返回true,up返回false:结果同二
1.首先是onTouch事件的down事件发生,然后是onTouch事件的up事件发生;
2.期间不触发onClick和onLongClick事件

日志:

不长按.png

长按.png

机制分析:

  1. onTouch事件中:down事件返回值标记此次事件是否为点击事件(返回false,是点击事件;返回true,不记为点击事件),

  2. 而up事件标记此次事件结束时间,也就是判断是否为长按。

3.只要当down返回true时候,系统将不把本次事件记录为点击事件,也就不会触发onClick或者onLongClick事件了。

4.因此尽管当up的时候返回false,系统也不会继续触发onClick事件了。

####四 . onTouch:down返回false,up返回true:
1.首先是onTouch事件的down事件发生,此时:
2.长按,触发onLongClick事件,然后是onTouch事件的up事件发生,完毕。
3.短按,先触发onTouch的up事件, 到一定时间后,自动触发onLongClick事件。

日志:

不长按.png

长按.png

机制分析:

  1. onTouch事件中:down事件返回值标记此次事件是否为点击事件(返回false,是点击事件;返回true,不记为点击事件),

  2. 而up事件标记此次事件结束时间,也就是判断是否为长按。

3.只要当down返回true时候,系统将把本次事件记录为点击事件,而up返回了true,表示一直没有结束,一直长按中,也就不会触发onClick事件了。

源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package com.example.h.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
private Button bntTest1,bntTest2,bntTest3,bntTest4;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bntTest1 = (Button) findViewById(R.id.bnt_test1);
bntTest2 = (Button) findViewById(R.id.bnt_test2);
bntTest3 = (Button) findViewById(R.id.bnt_test3);
bntTest4 = (Button) findViewById(R.id.bnt_test4);
bntTest1.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.e(TAG,"--bntTest1--onOnLongClick()触发----");
return false;
}
});
bntTest1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG,"--bntTest1---onClick()触发----");
}
});
bntTest1.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// Log.e(TAG,"--bntTest1---MotionEvent触发----"+event.getAction());
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"--bntTest1---MotionEvent.ACTION_DOWN:触发----");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"--bntTest1---MotionEvent.ACTION_UP:触发----");
break;
}
return false;
}
});
bntTest2.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.e(TAG,"--bntTest2--onOnLongClick()触发----");
return false;
}
});
bntTest2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG,"--bntTest2---onClick()触发----");
}
});
bntTest2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"--bntTest2---MotionEvent.ACTION_DOWN:触发----");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG,"--bntTest2---MotionEvent.ACTION_UP:触发----");
break;
}
return true;
}
});
bntTest3.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.e(TAG,"--bntTest3--onOnLongClick()触发----");
return false;
}
});
bntTest3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG,"--bntTest3---onClick()触发----");
}
});
bntTest3.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"--bntTest3---MotionEvent.ACTION_DOWN:触发----");
return true;
case MotionEvent.ACTION_UP:
Log.e(TAG,"--bntTest3---MotionEvent.ACTION_UP:触发----");
return false;
}
return false;
}
});
bntTest4.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
Log.e(TAG,"--bntTest4--onOnLongClick()触发----");
return false;
}
});
bntTest4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e(TAG,"--bntTest4---onClick()触发----");
}
});
bntTest4.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.e(TAG,"--bntTest4---MotionEvent.ACTION_DOWN:触发----");
return false;
case MotionEvent.ACTION_UP:
Log.e(TAG,"--bntTest4---MotionEvent.ACTION_UP:触发----");
return true;
}
return false;
}
});
}
}

##结语
本篇文章分析了Android事件分发机制之Button的OnTouch事件,为了方便读者理解,只需要记住down事件返回值标记此次事件是否为点击事件(返回false,是点击事件;返回true,不记为点击事件),而up事件标记此次事件结束时间这个关键点就好了。

##项目地址
https://github.com/ruanjiankeji/ButtonEventAnalysis

如有不足,欢迎小伙伴指正,相互学习;如果觉得还可以,欢迎文章star或者github上star、follow

文章目录
|