Android開(kāi)發(fā)學(xué)習(xí)教程(7)- 詳解Android Button點(diǎn)擊事件原理
2023-01-26 15:22 作者:考研保研直通車(chē) | 我要投稿
—— 只有你成功了,才有選擇的權(quán)力,才會(huì)被更多的人尊重。
上一篇我們知道了Button的基本用法,最后講到了Button的點(diǎn)擊事件是通過(guò)setOnClickListener方法來(lái)實(shí)現(xiàn)的。那么APP是如果把用戶的點(diǎn)擊動(dòng)作和setOnClickListener關(guān)聯(lián)起來(lái)的呢,要弄明白這個(gè)問(wèn)題,我們先來(lái)看看APP中是什么時(shí)侯處理用戶點(diǎn)擊動(dòng)作的。要看問(wèn)題還得從代碼看起,這里以上一篇中的Button基本用法項(xiàng)目舉例,打開(kāi)TestActivity點(diǎn)擊事件的主要代碼:
1
2
3
4
5
6
button.setOnClickListener(
new
?View.OnClickListener() {
????
@Override
????
public
?void
?onClick(View v) {
????????
Toast.makeText(TestActivity.
this
,?
"我被點(diǎn)擊了"
, Toast.LENGTH_SHORT).show();
????
}
});
我們來(lái)看setOnClickListener的源碼:
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
/**
?
* Register a?callback?to be invoked when this?view?is clicked. If this view is not
?
*?clickable, it becomes clickable.
?
*
?
* @param l The callback that will run
?
*
?
* @see #setClickable(boolean)
?
*/
public
?void
?setOnClickListener(
@Nullable
?OnClickListener l) {
????
if
?(!isClickable()) {
????????
setClickable(
true
);
????
}
????
getListenerInfo().mOnClickListener = l;
}
注釋寫(xiě)的很明白,注冊(cè)一個(gè)當(dāng)view被點(diǎn)擊時(shí)的回調(diào)方法??梢钥吹桨鸦卣{(diào)方案OnClickListener傳給了getListenerInfo().mOnClickListener,getListenerInfo()跟進(jìn)去:
static
?class
?ListenerInfo {
????
@UnsupportedAppUsage
????
ListenerInfo() {
????
}
...
...
}
一個(gè)靜態(tài)類(lèi)而已,里面定義了一堆接口,包括上面?zhèn)鬟f的點(diǎn)擊事件mOnClickListener ,那么mOnClickListener 什么時(shí)侯被調(diào)用,view里面有一個(gè)onTouchEvent方法:
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
/**
*實(shí)現(xiàn)此方法以處理觸摸屏幕移動(dòng)事件。
*包括:
*1. 播放單擊聲音
*2. 調(diào)用OnClickListener
*/
public
?boolean
?onTouchEvent(MotionEvent event) {
????
...
...
// 如果是可點(diǎn)擊的
????
if
?(clickable) {
????????
switch
?(action) {
// ACTION_UP 手指觸摸屏幕抬起事件
????????????
case
?MotionEvent.ACTION_UP:
????????????????
...
// 如果不可點(diǎn)擊的,那么移出所有相關(guān)回調(diào),并跳出循環(huán)
????????????????
if
?(!clickable) {
????????????????????
removeTapCallback();
????????????????????
removeLongPressCallback();
????????????????????
mInContextButtonPress =?
false
;
????????????????????
mHasPerformedLongPress =?
false
;
????????????????????
mIgnoreNextUpEvent =?
false
;
????????????????????
break
;
????????????????
}
// 如果view是被按下的狀態(tài)(說(shuō)明在手指按下時(shí)按的是這個(gè)view)
????????????????
if
?(prepressed) {
????????????????????
boolean
?focusTaken =?
false
;
????????????????????
if
?(isFocusable() && isFocusableInTouchMode() && !isFocused()) {
????????????????????????
focusTaken = requestFocus();
????????????????????
}
???????????????????????
// 設(shè)置按下?tīng)顟B(tài)
????????????????????
if
?(prepressed) {
????????????????????????
setPressed(
true
, x, y);
????????????????????
}
????????????????????
if
?(!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
// 能到這一步說(shuō)明是單擊事件,那么移除長(zhǎng)按事件的回調(diào)
????????????????????????
removeLongPressCallback();
????????????????????????
if
?(!focusTaken) {
????????????????????????????
// 創(chuàng)建一個(gè)執(zhí)行點(diǎn)擊回調(diào)的子線程
????????????????????????????
if
?(mPerformClick ==?
null
) {
????????????????????????????????
mPerformClick =?
new
?PerformClick();
????????????????????????????
}
// 把子線程添加到UI線程的消息對(duì)列中等待處理
????????????????????????????
if
?(!post(mPerformClick)) {
????????????????????????????????
performClickInternal();
????????????????????????????
}
????????????????????????
}
????????????????????
}
????????????????????
...
????????????????????
removeTapCallback();
????????????????
}
上面那個(gè)執(zhí)行點(diǎn)擊回調(diào)的子線程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public
?boolean
?performClick() {
????
...
????
final
?boolean
?result;
// 這里的mListenerInfo就是我們?cè)贏ctivity中setOnClickListener傳遞過(guò)來(lái)的
????
final
?ListenerInfo li = mListenerInfo;
????
if
?(li !=?
null
?&& li.mOnClickListener !=?
null
) {
????????
playSoundEffect(SoundEffectConstants.CLICK);
// 具體在這執(zhí)行回調(diào),即Activity中的public void onClick(View v) {...}
????????
li.mOnClickListener.onClick(
this
);
????????
result =?
true
;
????
}?
else
?{
????????
result =?
false
;
????
}
????
...
????
return
?result;
}
源碼鏈接:https://yunjunet.cn/876732.html
標(biāo)簽: