欢迎光临散文网 会员登陆 & 注册

Android开发学习教程(7)- 详解Android Button点击事件原理

2023-01-26 15:22 作者:考研保研直通车  | 我要投稿

—— 只有你成功了,才有选择的权力,才会被更多的人尊重。

上一篇我们知道了Button的基本用法,最后讲到了Button的点击事件是通过setOnClickListener方法来实现的。那么APP是如果把用户的点击动作和setOnClickListener关联起来的呢,要弄明白这个问题,我们先来看看APP中是什么时侯处理用户点击动作的。要看问题还得从代码看起,这里以上一篇中的Button基本用法项目举例,打开TestActivity点击事件的主要代码:

1
2
3
4
5
6
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(TestActivity.this"我被点击了", Toast.LENGTH_SHORT).show();
    }
});

我们来看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;
}
注释写的很明白,注册一个当view被点击时的回调方法。可以看到把回调方案OnClickListener传给了getListenerInfo().mOnClickListener,getListenerInfo()跟进去:
static class ListenerInfo {
    @UnsupportedAppUsage
    ListenerInfo() {
    }
...
...
}

一个静态类而已,里面定义了一堆接口,包括上面传递的点击事件mOnClickListener ,那么mOnClickListener 什么时侯被调用,view里面有一个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
/**
*实现此方法以处理触摸屏幕移动事件。
*包括:
*1. 播放单击声音
*2. 调用OnClickListener
*/
public boolean onTouchEvent(MotionEvent event) {
    ...
...
// 如果是可点击的
    if (clickable) {
        switch (action) {
// ACTION_UP 手指触摸屏幕抬起事件
            case MotionEvent.ACTION_UP:
                ...
// 如果不可点击的,那么移出所有相关回调,并跳出循环
                if (!clickable) {
                    removeTapCallback();
                    removeLongPressCallback();
                    mInContextButtonPress = false;
                    mHasPerformedLongPress = false;
                    mIgnoreNextUpEvent = false;
                    break;
                }
// 如果view是被按下的状态(说明在手指按下时按的是这个view)
                if (prepressed) {
                    boolean focusTaken = false;
                    if (isFocusable() && isFocusableInTouchMode() && !isFocused()) {
                        focusTaken = requestFocus();
                    }
                       // 设置按下状态
                    if (prepressed) {
                        setPressed(true, x, y);
                    }
                    if (!mHasPerformedLongPress && !mIgnoreNextUpEvent) {
// 能到这一步说明是单击事件,那么移除长按事件的回调
                        removeLongPressCallback();
                        if (!focusTaken) {
                            // 创建一个执行点击回调的子线程
                            if (mPerformClick == null) {
                                mPerformClick = new PerformClick();
                            }
// 把子线程添加到UI线程的消息对列中等待处理
                            if (!post(mPerformClick)) {
                                performClickInternal();
                            }
                        }
                    }
                    ...
                    removeTapCallback();
                }

上面那个执行点击回调的子线程:

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就是我们在Activity中setOnClickListener传递过来的
    final ListenerInfo li = mListenerInfo;
    if (li != null && li.mOnClickListener != null) {
        playSoundEffect(SoundEffectConstants.CLICK);
// 具体在这执行回调,即Activity中的public void onClick(View v) {...}
        li.mOnClickListener.onClick(this);
        result = true;
    else {
        result = false;
    }
    ...
    return result;
}

源码链接:https://yunjunet.cn/876732.html

Android开发学习教程(7)- 详解Android Button点击事件原理的评论 (共 条)

分享到微博请遵守国家法律