Android开发学习教程(8)- 详解Android Button点击事件原理
时间:2022-01-04 10:20:11 阅读数:15,112人阅读
作者:Android学习小站
版权声明:转载请注明出处,谢谢!
—— 只有你成功了,才有选择的权力,才会被更多的人尊重。
上一篇我们知道了Button的基本用法,最后讲到了Button的点击事件是通过setOnClickListener方法来实现的。那么APP是如果把用户的点击动作和setOnClickListener关联起来的呢,要弄明白这个问题,我们先来看看APP中是什么时侯处理用户点击动作的。要看问题还得从代码看起,这里以上一篇中的Button基本用法项目举例,打开TestActivity点击事件的主要代码:
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(TestActivity.this, "我被点击了", Toast.LENGTH_SHORT).show(); } });
我们来看setOnClickListener的源码:
/** * 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. 调用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(); }
上面那个执行点击回调的子线程:
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; }
------转载请注明出处,感谢您对原创作者的支持------
有偿提供技术支持、Bug修复、项目外包、毕业设计、大小作业
Android学习小站
Q Q:1095817610
微信:jx-helu
邮箱:1095817610@qq.com
添加请备注"Android学习小站"
