作筆記用,方便之後糊塗了,過來看看: java
貼代碼的話就太多了,可是不貼又怕之後看不明白: android
子View ide
import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.Button; import android.widget.TextView; public class MyTextView extends TextView { private static final String TAG = "內嵌TextView"; public MyTextView(Context context, AttributeSet attrs) { super(context, attrs); } public MyTextView(Context context){ super(context); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub System.out.println("TextView onTouchEvent Method is start&&"); if(MotionEvent.ACTION_DOWN == event.getAction()){ Log.v(TAG + " onTouchEvent:", "ACTION_DOWN"); }else if(MotionEvent.ACTION_MOVE == event.getAction()){ Log.v(TAG + " onTouchEvent:", "ACTION_MOVE"); }else{ Log.v(TAG + " onTouchEvent:", "ACTION_UP"); } return super.onTouchEvent(event); } }ViewGroup LinearLayout:
import android.content.Context; import android.graphics.Color; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.widget.LinearLayout; public class MyLinearLayout1 extends LinearLayout{ public MyLinearLayout1(Context context, AttributeSet attrs) { super(context, attrs); this.setBackgroundColor(Color.WHITE); } public MyLinearLayout1(Context context) { super(context); this.setBackgroundColor(Color.WHITE); } private String TAG = "第一層MyLinearLayout"; //該方法是用來分發觸摸事件的,確切說,應該是過濾觸摸事件的,若是return false的話,只能接收到DOWN事件,以後的好比MOVE、UP事件不會再繼續接收. @Override public boolean dispatchTouchEvent(MotionEvent event){ System.out.println("dispatchTouchEvent method is start **"); if(MotionEvent.ACTION_DOWN == event.getAction()){ Log.v(TAG + "dispatchTouchEvent:", "ACTION_DOWN"); }else if(MotionEvent.ACTION_MOVE == event.getAction()){ Log.v(TAG + "dispatchTouchEvent:", "ACTION_MOVE"); }else{ Log.v(TAG + "dispatchTouchEvent:", "ACTION_UP"); } super.dispatchTouchEvent(event); return true; } //該方法只會在dispatchTouchEvent調用了super.dispatchTouchEvent之後才會觸發。 //默認return false 只有return false子View才能接收到觸摸事件 @Override public boolean onInterceptTouchEvent(MotionEvent event){ System.out.println("onInterceptTouchEvent method is start##"); super.onInterceptTouchEvent(event); if(MotionEvent.ACTION_DOWN == event.getAction()){ Log.v(TAG + "onInterceptTouchEvent:", "ACTION_DOWN"); }else if(MotionEvent.ACTION_MOVE == event.getAction()){ Log.v(TAG + "onInterceptTouchEvent:", "ACTION_MOVE"); }else{ Log.v(TAG + "onInterceptTouchEvent:", "ACTION_UP"); } return false; } //該方法是用來消耗觸摸事件的 //默認return false。return true 的話,就表示該事件已經處理結束。 @Override public boolean onTouchEvent(MotionEvent event){ System.out.println("onTouchEvent method is start>>"); super.onTouchEvent(event); if(MotionEvent.ACTION_DOWN == event.getAction()){ Log.v(TAG + "onTouchEvent:", "ACTION_DOWN"); }else if(MotionEvent.ACTION_MOVE == event.getAction()){ Log.v(TAG + "onTouchEvent:", "ACTION_MOVE"); }else{ Log.v(TAG + "onTouchEvent:", "ACTION_UP"); } return true; } }xml
<com.testtouchevent.MyLinearLayout1 xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/am_linear" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <com.testtouchevent.MyTextView android:id="@+id/am_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" android:textSize="50sp"/> </com.testtouchevent.MyLinearLayout1>
|
是否調用super this |
return spa |
|
dispatchTouchEvent code |
|
true orm |
|
onInterceptTouchEvent xml |
super 事件 |
true ci |
|
onTouchEvent |
super |
true |
|
|
|
|
|
|
是否調用super |
return |
|
dispatchTouchEvent |
|
false |
|
onInterceptTouchEvent |
super |
true |
|
onTouchEvent |
super |
true |
|
也就是說若是dispatchTouchEvent返回的是false,就不在接收接下來一系列觸摸事件的處理了。並且沒調用super,也不會將event傳遞到另外兩個方法。
|
是否調用super |
return |
|
dispatchTouchEvent |
super |
true |
|
onInterceptTouchEvent |
super |
true |
|
onTouchEvent |
super |
true |
|
調用了 dispatchTouchEvent方法中調用了 super.dispatchTouchEvent()後,另外的兩個方法才得以調用。
其中只 dispatchTouchEvent return false:
同樣的不會處理down之後的事件,可是會將其給後面的兩個方法。
其中只 onInterceptTouchEvent return false
|
是否調用super |
return |
|
dispatchTouchEvent |
super |
false |
|
onInterceptTouchEvent |
super |
false |
|
onTouchEvent |
super |
false |
|
只接收down事件。之後的就不會再接收了。也就沒有點擊事件的處理情況,因為點擊的處理實在up之後進行的
2)
一、
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return false;
二、
dispatchTouchEvent return true:
onInterceptTouchEvent return true:
onTouchEvent return false;
能夠看到事件沒有分發給子view,這時若是LinearLayout也有觸摸的處理事件的話,好比Click那麼:
也就是說,LinearLayout會響應點擊事件
三、
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return false;
相比較2例子而言,若是onInterceptTouchEvent return 的是false 那麼會先向下傳遞,最終TextView會獲得事件的最終處理權。
四、
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return true;
可見向下傳遞後,子View處理完Click事件後,點擊事件已經消耗,因此LinearLayout不會在有點擊事件的響應。
五、
dispatchTouchEvent return true:
onInterceptTouchEvent return true:
onTouchEvent return true;
反正不會再向下傳遞,子view獲取不到事件了,因此onTouchEvent返回什麼就沒什麼大的關係了。
六、子view onTouchEvent return 的是false
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return true;//false
執行了Activity中LinearLayout的點擊事件
七、子view onTouchEvent return 的是true
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return true;//false
沒有執行Activity中TextView的點擊事件。