龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 移动开发 > Android开发 >

Android Touch事件分发过程详解(6)

时间:2014-09-12 02:14来源:网络整理 作者:网络 点击:
分享到:
我们看到,在onTouchEvent函数中就是对ACTION_UP、ACTION_DOWN、ACTION_MOVE等几个事件进行处理,而最重要的就是UP事件了,因为这个里面包含了对用户点击事件的处

我们看到,在onTouchEvent函数中就是对ACTION_UP、ACTION_DOWN、ACTION_MOVE等几个事件进行处理,而最重要的就是UP事件了,因为这个里面包含了对用户点击事件的处理,或者是说对于用户而言相对重要一点,因此放在了第一个case中。在ACTION_UP事件中会判断该view是否enable、是否clickable、是否获取到了焦点,然后我们看到会通过post方法将一个PerformClick对象投递给UI线程,如果投递失败则直接调用performClick函数执行点击事件。

/** 
 * Causes the Runnable to be added to the message queue. 
 * The runnable will be run on the user interface thread. 
 * 
 * @param action The Runnable that will be executed. 
 * 
 * @return Returns true if the Runnable was successfully placed in to the 
 *     message queue. Returns false on failure, usually because the 
 *     looper processing the message queue is exiting. 
 */ 
public boolean post(Runnable action) { 
  Handler handler; 
  if (mAttachInfo != null) { 
    handler = mAttachInfo.mHandler; 
  } else { 
    // Assume that post will succeed later 
    ViewRoot.getRunQueue().post(action); 
    return true; 
  } 
 
  return handler.post(action); 
} 

我们看看PerformClick类吧。

private final class PerformClick implements Runnable { 
  public void run() { 
    performClick(); 
  } 
} 

可以看到,其内部就是包装了View类中的performClick()方法。再看performClick()方法:

/** 
 * 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(OnClickListener l) { 
   if (!isClickable()) { 
     setClickable(true); 
   } 
   mOnClickListener = l; 
 } 
 
 /** 
 * Call this view's OnClickListener, if it is defined. 
 * 
 * @return True there was an assigned OnClickListener that was called, false 
 *     otherwise is returned. 
 */ 
 public boolean performClick() { 
   sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED); 
 
   if (mOnClickListener != null) { 
     playSoundEffect(SoundEffectConstants.CLICK); 
     mOnClickListener.onClick(this); 
     return true; 
   } 
 
   return false; 
 } 

代码很简单,主要就是调用了mOnClickListener.onClick(this);方法,即执行用户通过setOnClickListener设置进来的点击事件处理Listener。
 
总结

用户触摸屏幕产生一个触摸消息,系统底层将该消息转发给ViewRoot ( ViewRootImpl ),ViewRoot产生一个DISPATCHE_POINTER的消息,并且在handleMessage中处理该消息,最终会通过deliverPointerEvent(MotionEvent event)来处理该消息。在该函数中会调用mView.dispatchTouchEvent(event)来分发消息,该mView是一个ViewGroup类型,因此是ViewGroup的dispatchTouchEvent(event),在该函数中会遍历所有的child view,找到该事件的触发的左边与每个child view的坐标进行对比,如果触摸的坐标在该child view的范围内,则由该child view进行处理。如果该child view是ViewGroup类型,则继续上一步的查找过程;否则执行View中的dispatchTouchEvent(event)函数。在View的dispatchTouchEvent(event)中首先判断该控件是否enale以及mOnTouchListent是否为空,如果mOnTouchListener不为空则执行mOnTouchListener.onTouch(event)方法,如果该方法返回false则再执行View中的onTouchEvent(event)方法,并且在该方法中执行mOnClickListener.onClick(this, event) ;方法; 如果mOnTouchListener.onTouch(event)返回true则不会执行onTouchEvent方法,因此点击事件也不会被执行。

粗略的流程图如下 :

相信本文所述对大家进一步深入掌握Android程序设计有一定的借鉴价值。

收藏文章
表情删除后不可恢复,是否删除
取消
确定
图片正在上传,请稍后...
评论内容为空!
还没有评论,快来抢沙发吧!

热评话题

按钮 内容不能为空!
立刻说两句吧! 查看0条评论
精彩图集

赞助商链接