1普通的控件,buttom,Textview。。。。
PRivate LinearLayout mLayout; private Button mButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLayout = (LinearLayout) this.findViewById(R.id.mylayout); mButton = (Button) this.findViewById(R.id.my_btn); mLayout.setOnTouchListener(this); mButton.setOnTouchListener(this); mLayout.setOnClickListener(this); mButton.setOnClickListener(this); } @Override public void onClick(View v) { Log.i("lyf", "OnClickListener--onClick--" + v); } //public static final int ACTION_DOWN = 0; //public static final int ACTION_UP = 1; //public static final int ACTION_MOVE = 2; @Override public boolean onTouch(View v, MotionEvent event) { Log.i("lyf", "OnTouchListener--onTouch-- action=" + event.getAction() + " --" + v); return false; }情景1、可以看到我們onTouch方法返回false,不消費該事件,往下層傳遞。
I/lyf: OnTouchListener--onTouch-- action=0 --android.widget.Button I/lyf: OnTouchListener--onTouch-- action=2 --android.widget.ButtonI/lyf: OnTouchListener--onTouch-- action=2 --android.widget.ButtonI/lyf: OnTouchListener--onTouch-- action=2 --android.widget.ButtonI/lyf: OnTouchListener--onTouch-- action=2 --android.widget.Button I/lyf: OnTouchListener--onTouch-- action=1 --android.widget.ButtonI/lyf: OnClickListener--onClick--android.widget.Button情景2、在onTouch方法返回true,消費該事件,不往下層傳遞了。onClick方法自然而然也沒有接收到信息了,至于為什么不傳遞到onClick方法里面,我們來看看源碼就知道了:
if (!mHasperformedLongPress) { // This is a tap, so remove the longpress check removeLongPressCallback(); // Only perform take click actions if we were in the pressed state if (!focusTaken) { // Use a Runnable and post this rather than calling // performClick directly. This lets other visual state // of the view update before click actions start. *if (mPerformClick == null) { mPerformClick = new PerformClick(); } if (!post(mPerformClick)) { performClick(); } }* }performClick()這個方法就是關于點擊事件的,而這個方法是在onTouchEvent方法里面,而 onTouch方法又優先于onTouchEvent方法,那再看看為什么onTouch優先于onTouchEvent吧! public boolean dispatchTouchEvent(MotionEvent event){ ... ... if(onFilterTouchEventForSecurity(event)){ ListenerInfo li = mListenerInfo; if(li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && li.mOnTouchListener.onTouch(this, event)) { return true; } if(onTouchEvent(event)){ return true; } } ... ... return false; }li.mOnTouchListener.onTouch()這個方法就在分發事件中調用, 為什么onTouch方法執行優先于onTouchEvent,跟蹤源碼:很明顯可以看到,事件的傳遞,會優先掉用mOnTouchListener.onTouch(this, event)這個方法,然后才能輪到onTouchEvent(event)獲取事件,順序如此,有什么可說。既然說到這里,我們也應該想起了onClick和onLongPressClic都是對onTouchEvent(event)的依賴,如果在setOnTouchListener.onTouch()的時候返回true,那么onTouchEvent方法不會被調用。同樣,內置諸如click事件的實現等等都基于onTouchEvent,假如onTouch返回true,這些事件將不會被觸發。因為有3個判斷滿足的情況下,就不會進入onTouchEvent了,只有不滿足的情況下才會進入。I/lyf: OnTouchListener--onTouch-- action=0 --android.widget.ButtonI/lyf: OnTouchListener--onTouch-- action=2 --android.widget.ButtonI/lyf: OnTouchListener--onTouch-- action=2 --android.widget.ButtonI/lyf: OnTouchListener--onTouch-- action=1 --android.widget.Button最后,在這里總結一點,上面2個列子,onTouch-onClick,如果消費了,點擊就沒有效果了。
2自定義一個控件來實現dispatchTouchEvent(觸摸事件分發)、onTouchEvent(觸摸事件)、在Activity中實現onTouch方法和onClick方法。在這里我只是記錄一下事件分發的日志,以方便日后不用每次的測試一下。
情景1;
public class TestButton extends Button { ........................... @Override public boolean dispatchTouchEvent(MotionEvent event) { Log.i("lyf", "dispatchTouchEvent-- action=" + event.getAction()); return super.dispatchTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { Log.i("lyf", "onTouchEvent-- action="+event.getAction()); return super.onTouchEvent(event); }}public class ListenerActivity extends Activity implements View.OnTouchListener, View.OnClickListener { ................................ @Override public boolean onTouch(View v, MotionEvent event) { Log.i("lyf", "OnTouchListener--onTouch-- action=" + event.getAction() + " --" + v); return false; } @Override public void onClick(View v) { Log.i("lyf", "OnClickListener--onClick--" + v); }}結果: “ I/lyf: dispatchTouchEvent– action=0 I/lyf: onTouch– action=0 I/lyf: onTouchEvent– action=0 I/lyf: dispatchTouchEvent– action=2 I/lyf: onTouch– action=2 I/lyf: onTouchEvent– action=2 I/lyf: dispatchTouchEvent– action=1 I/lyf: onTouch– action=1 I/lyf: onTouchEvent– action=1 I/lyf: onClick–com.example.xiaolin.mytochuview.TestButton
可以看到事件分發由上車到下車,中途沒有乘客,哈哈,不知道這樣說對不對了!,寫到這里就不寫了,大家可以自行修改值,來看看結果,中途可以上車,也可以下車,。。最后,重點,返回值,@Overridepublic boolean dispatchTouchEvent(MotionEvent event) { Log.i("lyf", "dispatchTouchEvent-- action=" + event.getAction()); return true;}再看一下結果:com.example.xiaolin.mytochuview I/lyf: dispatchTouchEvent– action=0 com.example.xiaolin.mytochuview I/lyf: dispatchTouchEvent– action=2 com.example.xiaolin.mytochuview I/lyf: dispatchTouchEvent– action=2 com.example.xiaolin.mytochuview I/lyf: dispatchTouchEvent– action=2 com.example.xiaolin.mytochuview I/lyf: dispatchTouchEvent– action=2 com.example.xiaolin.mytochuview I/lyf: dispatchTouchEvent– action=1 “` 返回值為true,不再往下傳遞了(消費了該事件),false(沒有消費該事件)!
|
新聞熱點
疑難解答