做笔记用,方便以后糊涂了,过来看看:
贴代码的话就太多了,但是不贴又怕以后看不明白:
子View
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 | return |
|
dispatchTouchEvent |
| true |
|
onInterceptTouchEvent | super | true |
|
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
四、在ViewGroup中添加子View,並且設置了onClick之後:
1)
| 是否調用super | return |
|
dispatchTouchEvent | super | false |
|
onInterceptTouchEvent | super | false |
|
onTouchEvent | super | false |
|
只接收down事件。之後的就不會再接收了。也就沒有點擊事件的處理情況,因為點擊的處理實在up之後進行的
2)
1、
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return false;
2、
dispatchTouchEvent return true:
onInterceptTouchEvent return true:
onTouchEvent return false;
可以看到事件沒有分發給子view,這時如果LinearLayout也有觸摸的處理事件的話,比如Click那麼:
也就是說,LinearLayout會響應點擊事件
3、
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return false;
相比較2例子而言,如果onInterceptTouchEvent return 的是false 那麼會先向下傳遞,最終TextView會得到事件的最終處理權。
4、
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return true;
可見向下傳遞後,子View處理完Click事件後,點擊事件已經消耗,所以LinearLayout不會在有點擊事件的響應。
5、
dispatchTouchEvent return true:
onInterceptTouchEvent return true:
onTouchEvent return true;
反正不會再向下傳遞,子view獲取不到事件了,所以onTouchEvent返回什麼就沒什麼大的關係了。
上面的例子都是子View的onTouchEvent return super.onTouchEvent(event); 下面我們手動的改一下讓他return false or true
6、子view onTouchEvent return 的是false
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return true;//false
執行了Activity中LinearLayout的點擊事件
7、子view onTouchEvent return 的是true
dispatchTouchEvent return true:
onInterceptTouchEvent return false:
onTouchEvent return true;//false
沒有執行Activity中TextView的點擊事件。