onTouch onTouchEvent 与 onClick三者调用先后分析
来源:互联网 发布:淘宝号可以不实名认证 编辑:程序博客网 时间:2024/05/19 09:50
看代码,这里初始化了一个自定义的TextView,为它设了OnTouchListener和OnClickListener分别对应onTouch和onClick方法:
public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnTouchListener { private static final String TAG = "MainActivity"; private MyTextView myTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myTextView = (MyTextView) findViewById(R.id.mytextview); myTextView.setOnClickListener(this); myTextView.setOnTouchListener(this); } @Override public void onClick(View view) { Log.d(TAG,"onClick"); } @Override public boolean onTouch(View view, MotionEvent motionEvent) { Log.d(TAG,"onTouch"); return false; }}
在自定义的TextView中,我们设置了OnTouchEvent监听
public class MyTextView extends TextView { private static final String TAG = "MyTextView"; public MyTextView(Context context) { super(context); } public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); } public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } //第一步 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(measureWidth(widthMeasureSpec),measureHeight(heightMeasureSpec)); } private int measureHeight(int measureSpec) { int result = 0; int mode = MeasureSpec.getMode(measureSpec); int size = MeasureSpec.getSize(measureSpec); if (mode == MeasureSpec.EXACTLY){ result = size; } else { result = 200; if (mode == MeasureSpec.AT_MOST){ result = Math.min(result,size); } } return result; } private int measureWidth(int measureSpec) { int result = 0; int mode = MeasureSpec.getMode(measureSpec); int size = MeasureSpec.getSize(measureSpec); if (mode == MeasureSpec.EXACTLY){ result = size; } else { result = 200; if (mode == MeasureSpec.AT_MOST){ result = Math.min(result,size); } } return result; } //第二步 @Override protected void onDraw(Canvas canvas) { //绘制文本内容前 super.onDraw(canvas); //绘制文本内容后 } @Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG,"onTouchEvent"); return super.onTouchEvent(event); }}
可以看到这三个监听方法我们都打了Log,那我们在下运行过程:
02-16 04:23:48.566 25076-25076/lwp.myview D/MainActivity: onTouch02-16 04:23:48.566 25076-25076/lwp.myview D/MyTextView: onTouchEvent02-16 04:23:48.577 25076-25076/lwp.myview D/MainActivity: onTouch02-16 04:23:48.577 25076-25076/lwp.myview D/MyTextView: onTouchEvent02-16 04:23:48.584 25076-25076/lwp.myview D/MainActivity: onTouch02-16 04:23:48.585 25076-25076/lwp.myview D/MyTextView: onTouchEvent02-16 04:23:48.585 25076-25076/lwp.myview D/SettingsInterface: from settings cache , name = sound_effects_enabled , value = 002-16 04:23:48.585 25076-25076/lwp.myview D/MainActivity: onClick
这里我们看到,(1)onTouch最先执行,(2)然后是onTouchEvent,由于onTouch返回了false所以onTouchEvent可以执行,在经历若干次的(1)(2)重复之后,当我手抬起的时候,才会进行onClick操作,对于OnTouch(Activity中setOnTouchListener)->onTouchEvent(view中)->onClick(Activity中setOnClickListener)我们是没有疑问的,这是在onTouchEvent 返回super.onTouchEvent(event)的情况下并且onTouch返回false,但是如果onTouchEvent返回了false(onTouch返回true我就不说了,因为它一旦返回true,onClick和onTouchEvent就根本不会执行),那么点击这个TextView一次,无论长按多久,在一次down-(move)-up里,只会提示一次:
02-16 23:50:00.078 17772-17772/lwp.myview D/MainActivity: onTouch02-16 23:50:00.088 17772-17772/lwp.myview D/MyTextView: onTouchEvent
好的,让我们看下这三个按,移,抬,更加深入的看下:
@Override public boolean onTouchEvent(MotionEvent event) { Log.d(TAG,"onTouchEvent"); switch (event.getAction()){ case MotionEvent.ACTION_DOWN: Log.d(TAG,"ACTION_DOWN"); break; case MotionEvent.ACTION_MOVE: Log.d(TAG,"ACTION_MOVE"); break; case MotionEvent.ACTION_UP: Log.d(TAG,"ACTION_UP"); break; }// return super.onTouchEvent(event); return false;// return false; }
Log如下:
02-16 23:53:40.589 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:53:40.589 17772-17772/lwp.myview D/MyTextView: ACTION_DOWN
好的,这样我们就发现了,当onTouchEvent返回了false,那也就是它在接受到down事件之后返回了false,之后的move,up也就不会交给onTouchEvent处理了,自然就打印一次;那如果是return了true的话,照这个理解,应该是down,up,move都会执行,并且会执行多次,那我们看下:
02-16 23:57:06.467 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.485 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.485 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.500 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.500 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.517 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.517 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.534 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.534 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.562 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.562 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.620 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.620 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.656 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.656 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.666 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.666 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.684 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.685 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.706 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.707 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.733 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.733 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.756 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.756 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.773 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.773 17772-17772/lwp.myview D/MyTextView: ACTION_MOVE02-16 23:57:06.779 17772-17772/lwp.myview D/MyTextView: onTouchEvent02-16 23:57:06.779 17772-17772/lwp.myview D/MyTextView: ACTION_UP
看结果,确实如此。
由此,我们的出结论:
1.onTouch返回true,则onTouchEvent和onClick都不会执行;
2.onTouch(onTouchListener)返回false,如果onTouchEvent不是返回super.onTouchEvent(event);也就算是说不管onTouchEvent返回true还是false,onClick(onCLickListener)都不会执行,这可以从super的源码看出(源码里会进行判断执行到OnCLickListener),而且我们知道onClick执行也就会在触摸抬起(up)的时候执行;
- onTouch onTouchEvent 与 onClick三者调用先后分析
- onClick、onTouch、onTouchEvent的调用
- Android触摸屏事件派发机制详解与源码分析三(Activity篇)dispatchtouchevent,ontouch,ontouchevent,onclick
- Android触摸屏事件派发机制详解与源码分析一(View篇)onTouch,onClick,ontouchevent
- Android触摸屏事件派发机制详解与源码分析二(ViewGroup篇)dispatchtouchevent,ontouch,ontouchevent,onclick
- OnTouch(),onTouchEvent(),onClick()的区别
- Android 中 onTouch 和OnClick 冲突的处理(onTouchEvent返回true时与onclick冲突)
- android onTouch 与 onTouchEvent
- android开发中的OnTouch onClick onTouchEvent研究
- view中事件ontouch与ontouchEvent源码分析
- onInterceptTouchEvent()与onTouchEvent()与onTouch()
- onTouchEvent与onClick,onLongClick
- 浅谈 onInterceptTouchEvent、onTouchEvent与onTouch
- 浅谈onInterceptTouchEvent、onTouchEvent与onTouch
- 浅谈onInterceptTouchEvent、onTouchEvent与onTouch
- 浅谈onInterceptTouchEvent、onTouchEvent与onTouch
- 浅谈onInterceptTouchEvent、onTouchEvent与onTouch
- 浅谈onInterceptTouchEvent、onTouchEvent与onTouch
- C++指针和引用的区别与联系
- [BZOJ]1565: [NOI2009]植物大战僵尸 Tarjan+最小割(最大权闭合子图)
- 高精度加减乘法模板
- 深度学习和自然语言处理的应用和脉络2-复杂模型,最大熵-隐马尔科夫模型-条件随机场
- < 笔记 > DOM
- onTouch onTouchEvent 与 onClick三者调用先后分析
- Ubuntu16.04配置ADB调试环境
- 破解IDEA2017
- iOS11 导航栏按钮位置问题的解决------新
- javaweb接口安全校验预备知识——spring 拦截器interceptor的使用
- LeetCode--Minimum Window Substring
- http://blog.csdn.net/anxpp/article/details/52108238
- asp.net如何上传文件(修改服务器来支持所有的文件格式)
- Linux下命令笔记