Android 讓人又愛又恨的觸摸機制(二)

概述:

在上回,從原理上講解了android中觸摸機制的運行模式,那麼此次咱們經過代碼來驗證一下這個結論。是驢子是馬拿出來遛一遛吧。另外,所學知識有限,若是有任何問題歡迎拍磚和交流。java

補充一下,其實我寫的(一)中,存在一些問題,對於三個與觸摸機制息息相關的方法,並非上文說的那麼容統,細分而言。只有ViewGroup才徹底擁有這三個方法(onTouchEvent,onInterceptTouchEvent,dispatchTouchEvent),而對於View並無onInterceptTouchEvent,其實理由很簡單,我已是最小單位了,我還須要攔截麼?我下面已經木有東東能夠接收了~android

案例驅動:

MainActivity.class
這裏拋出一個問題,有興趣能夠回答一下:activity和View是什麼關係呢?是否是感受二者好像都是界面?仍是另有隱情呢?git

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MainActivity  extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
 
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
System.out.println( "MainActivity---dispatchTouchEvent---ACTION_DOWN" );
break ;
case MotionEvent.ACTION_UP:
System.out.println( "MainActivity---dispatchTouchEvent---ACTION_UP" );
break ;
default :
break ;
}
boolean result =  super .dispatchTouchEvent(event);
System.out.println( "MainActivity---dispatchTouchEvent---result:" +result);
return result;
}
}

自定義Button,做爲最小View單位,是沒有onInterceptTouchEvent方法能夠複寫的。其中只複寫了其餘兩個方法。windows

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MyButton  extends Button {
 
public MyButton(Context context, AttributeSet attrs) {
super (context, attrs);
}
 
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN)
System.out.println( "MyButton---onTouchEvent---ACTION_DOWN" );
if (action == MotionEvent.ACTION_MOVE)
System.out.println( "MyButton---onTouchEvent---ACTION_MOVE" );
if (action == MotionEvent.ACTION_UP)
System.out.println( "MyButton---onTouchEvent---ACTION_UP" );
return true ;
}
 
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN)
System.out.println( "MyButton---dispatchTouchEvent---ACTION_DOWN" );
if (action == MotionEvent.ACTION_MOVE)
System.out.println( "MyButton---dispatchTouchEvent---ACTION_MOVE" );
if (action == MotionEvent.ACTION_UP)
System.out.println( "MyButton---dispatchTouchEvent---ACTION_UP" );
boolean result =  super .dispatchTouchEvent(event);
System.out.println( "MyButton---dispatchTouchEvent---result:" +result);
return result;
}
 
}

自定義ViewGroup的子類,MyLinearLayout,能夠看到它是存在onInterceptTouchEvent方法,對於其中的子View,它能夠進行攔截或者不攔截。jsp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class MyLinearLayout  extends LinearLayout {
 
public MyLinearLayout(Context context, AttributeSet attrs) {
super (context, attrs);
}
 
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN)
System.out.println( "MyLinearLayout---onTouchEvent---ACTION_DOWN" );
if (action == MotionEvent.ACTION_MOVE)
System.out.println( "MyLinearLayout---onTouchEvent---ACTION_MOVE" );
if (action == MotionEvent.ACTION_UP)
System.out.println( "MyLinearLayout---onTouchEvent---ACTION_UP" );
boolean result =  super .onTouchEvent(event);
System.out.println( "MyLinearLayout---onTouchEvent---result:" +result);
return result;
}
 
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN)
System.out.println( "MyLinearLayout---onInterceptTouchEvent---ACTION_DOWN" );
if (action == MotionEvent.ACTION_MOVE)
System.out.println( "MyLinearLayout---onInterceptTouchEvent---ACTION_MOVE" );
if (action == MotionEvent.ACTION_UP)
System.out.println( "MyLinearLayout---onInterceptTouchEvent---ACTION_UP" );
boolean result =  super .onInterceptTouchEvent(event);
result =  true ;
System.out.println( "MyLinearLayout---onInterceptTouchEvent---result:" +result);
return result;
}
 
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN)
System.out.println( "MyLinearLayout---dispatchTouchEvent---ACTION_DOWN" );
if (action == MotionEvent.ACTION_MOVE)
System.out.println( "MyLinearLayout---dispatchTouchEvent---ACTION_MOVE" );
if (action == MotionEvent.ACTION_UP)
System.out.println( "MyLinearLayout---dispatchTouchEvent---ACTION_UP" );
boolean result =  super .dispatchTouchEvent(event);
System.out.println( "MyLinearLayout---dispatchTouchEvent---result:" +result);
return result;
}
}

自定義ImageView,和自定義Button相同,做爲最小View單位,不存在onInterceptTouchEventide

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class MyImageView  extends ImageView {
 
public MyImageView(Context context, AttributeSet attrs) {
super (context, attrs);
}
 
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN)
System.out.println( "MyImageView---dispatchTouchEvent---ACTION_DOWN" );
if (action == MotionEvent.ACTION_MOVE)
System.out.println( "MyImageView---dispatchTouchEvent---ACTION_MOVE" );
if (action == MotionEvent.ACTION_UP)
System.out.println( "MyImageView---dispatchTouchEvent---ACTION_UP" );
boolean result =  super .dispatchTouchEvent(event);
System.out.println( "MyImageView---dispatchTouchEvent---result:" +result);
return result;
}
 
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN)
System.out.println( "MyImageView---onTouchEvent---ACTION_DOWN" );
if (action == MotionEvent.ACTION_MOVE)
System.out.println( "MyImageView---onTouchEvent---ACTION_MOVE" );
if (action == MotionEvent.ACTION_UP)
System.out.println( "MyImageView---onTouchEvent---ACTION_UP" );
return true ;
}
}

最後看一下佈局文件,很簡單,這裏不贅述了。佈局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android"
xmlns:tools= "http://schemas.android.com/tools"
android:layout_width= "match_parent"
android:layout_height= "match_parent"
tools:context= ".MainActivity" >
 
<TextView
android:id= "@+id/title"
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:layout_centerHorizontal= "true"
android:layout_marginTop= "10dp"
android:textStyle= "bold"
android:textColor= "@color/blue"
android:text= "@string/touch" />
 
<com.example.touchevent.MyButton
android:id= "@+id/button1"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:layout_below= "@id/title"
android:layout_marginTop= "10dp"
android:text= "@string/mybutton1" />
 
<com.example.touchevent.MyLinearLayout
android:layout_width= "match_parent"
android:layout_height= "match_parent"
android:layout_below= "@id/button1"
android:layout_marginTop= "50dp"
android:background= "@color/blue"
android:gravity= "center" >
 
<com.example.touchevent.MyRelativeLayout
android:layout_width= "200dp"
android:layout_height= "200dp"
android:gravity= "center"
android:background= "@color/dark_gray" >
<com.example.touchevent.MyImageView
android:layout_width= "100dp"
android:layout_height= "100dp"
android:scaleType= "fitCenter"
android:src= "@drawable/jacky"
/>
</com.example.touchevent.MyRelativeLayout>
</com.example.touchevent.MyLinearLayout>
 
</RelativeLayout>

最終的效果圖以下
touchthis

當我手指按在圖中的1號區域(即屏幕空白處),而且稍微移動一下後再擡起,輸出結果以下:spa

1
2
3
4
5
6
7
8
9
10
11
12
03 - 20 21 : 00 : 59.428 : I/System.out( 3429 ): MainActivity---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 00 : 59.428 : I/System.out( 3429 ): MainActivity---onTouchEvent---ACTION_DOWN
03 - 20 21 : 00 : 59.428 : I/System.out( 3429 ): MainActivity---onTouchEvent---result: false
03 - 20 21 : 00 : 59.428 : I/System.out( 3429 ): MainActivity---dispatchTouchEvent---result: false
03 - 20 21 : 00 : 59.438 : I/System.out( 3429 ): MainActivity---dispatchTouchEvent---ACTION_MOVE
03 - 20 21 : 00 : 59.438 : I/System.out( 3429 ): MainActivity---onTouchEvent---ACTION_MOVE
03 - 20 21 : 00 : 59.438 : I/System.out( 3429 ): MainActivity---onTouchEvent---result: false
03 - 20 21 : 00 : 59.438 : I/System.out( 3429 ): MainActivity---dispatchTouchEvent---result: false
03 - 20 21 : 00 : 59.588 : I/System.out( 3429 ): MainActivity---dispatchTouchEvent---ACTION_UP
03 - 20 21 : 00 : 59.588 : I/System.out( 3429 ): MainActivity---onTouchEvent---ACTION_UP
03 - 20 21 : 00 : 59.588 : I/System.out( 3429 ): MainActivity---onTouchEvent---result: false
03 - 20 21 : 00 : 59.588 : I/System.out( 3429 ): MainActivity---dispatchTouchEvent---result: false

這裏你可能有疑問,爲何在執行了dispatchTouchEvent後,沒有輸出任何信息,而是先執行了onTouchEvent呢?這是由於在dispatchTouchEvent中執行了super.dispatchTouchEvent(event),而在這裏面執行了onTouchEvent方法,因此dispatchTouchEvent輸出比onTouchEvent輸出要慢一步。code

當手指在Button上按下並移動後離開的輸出結果以下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MainActivity---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MyButton---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MyButton---onTouchEvent---ACTION_DOWN
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MyButton---onTouchEvent---result: true
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MyButton---dispatchTouchEvent---result: true
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MainActivity---dispatchTouchEvent---result: true
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MainActivity---dispatchTouchEvent---ACTION_MOVE
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MyButton---dispatchTouchEvent---ACTION_MOVE
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MyButton---onTouchEvent---ACTION_MOVE
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MyButton---onTouchEvent---result: true
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MyButton---dispatchTouchEvent---result: true
03 - 20 21 : 07 : 29.947 : I/System.out( 5054 ): MainActivity---dispatchTouchEvent---result: true
03 - 20 21 : 07 : 29.957 : I/System.out( 5054 ): MainActivity---dispatchTouchEvent---ACTION_UP
03 - 20 21 : 07 : 29.957 : I/System.out( 5054 ): MyButton---dispatchTouchEvent---ACTION_UP
03 - 20 21 : 07 : 29.957 : I/System.out( 5054 ): MyButton---onTouchEvent---ACTION_UP
03 - 20 21 : 07 : 29.957 : I/System.out( 5054 ): MyButton---onTouchEvent---result: true
03 - 20 21 : 07 : 29.957 : I/System.out( 5054 ): MyButton---dispatchTouchEvent---result: true
03 - 20 21 : 07 : 29.957 : I/System.out( 5054 ): MainActivity---dispatchTouchEvent---result: true

從上面兩個輸出結果,能夠判斷Activity實際上是是你進入整個屏幕的第一道關卡,若是說activity在dispatchTouchEvent這裏返回false的話,而且不執行super.dispatchTouchEvent(event)的話,那麼整個屏幕中其餘的全部ViewGroup或者View都將失去任何觸摸效果。輸入結果以下輸出所示,每三個組成一組,由於觸摸的區域不一樣,每次只觸發了MainActivity的中的分發方法,可是顯然被攔截了。

1
2
3
4
5
6
7
8
9
10
11
12
03 - 20 20 : 48 : 49.709 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_DOWN
03 - 20 20 : 48 : 49.739 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_MOVE
03 - 20 20 : 48 : 49.749 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_UP
03 - 20 20 : 48 : 50.300 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_DOWN
03 - 20 20 : 48 : 50.320 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_MOVE
03 - 20 20 : 48 : 50.330 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_UP
03 - 20 20 : 48 : 50.820 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_DOWN
03 - 20 20 : 48 : 50.850 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_MOVE
03 - 20 20 : 48 : 50.870 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_UP
03 - 20 20 : 48 : 51.741 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_DOWN
03 - 20 20 : 48 : 51.771 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_MOVE
03 - 20 20 : 48 : 51.771 : I/System.out( 2335 ): MainActivity---dispatchTouchEvent---ACTION_UP

那麼這裏首先就有一個疑問產生了,super.dispatchTouchEvent中到底發生了什麼事情,那麼咱們進去看一看源碼。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Called to process touch screen events. You can override this to
* intercept all touch screen events before they are dispatched to the
* window. Be sure to call this implementation for touch screen events
* that should be handled normally.
*
* @param ev The touch screen event.
*
* @return boolean Return true if this event was consumed.
*/
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
onUserInteraction();
}
if (getWindow().superDispatchTouchEvent(ev)) {
return true ;
}
return onTouchEvent(ev);
}

其中調用了onUserInteraction方法,能夠看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Called whenever a key, touch, or trackball event is dispatched to the
* activity. Implement this method if you wish to know that the user has
* interacted with the device in some way while your activity is running.
* This callback and {@link #onUserLeaveHint} are intended to help
* activities manage status bar notifications intelligently; specifically,
* for helping activities determine the proper time to cancel a notfication.
*
*
All calls to your activity's {@link #onUserLeaveHint} callback will
* be accompanied by calls to {@link #onUserInteraction}. This
* ensures that your activity will be told of relevant user activity such
* as pulling down the notification pane and touching an item there.
*
*
Note that this callback will be invoked for the touch down action
* that begins a touch gesture, but may not be invoked for the touch-moved
* and touch-up actions that follow.
*
* @see #onUserLeaveHint()
*/
public void onUserInteraction() {
}

從源碼中能夠看到,dispatchTouchEvent方法只處理了ACTION_DOWN事件,全部的事件都是以按下爲起點的,因此,Android認爲當ACTION_DOWN事件沒有執行時,後面的事件都是沒有意義的,因此這裏首先判斷ACTION_DOWN事件。若是事件成立,則調用了onUserInteraction方法,該方法能夠在Activity中被重寫,在事件被分發前會調用該方法。該方法的返回值是void型,其中的方法體式空的,並不會對事件形成任何影響,而且接着會判斷getWindow().superDispatchTouchEvent(ev)的執行結果,看看它的源碼:

1
2
3
4
5
6
7
/**
* Used by custom windows, such as Dialog, to pass the touch screen event
* further down the view hierarchy. Application developers should
* not need to implement or call this.
*
*/
public abstract boolean superDispatchTouchEvent(MotionEvent event);

首先是個抽象方法,註釋中解釋到該方法用於自定義的Window,例如自定義Dialog從而傳遞觸摸事件,而且提到開發者不須要去實現或調用該方法,系統會完成,若是咱們在MainActivity中將dispatchTouchEvent方法的返回值設爲true,那麼這裏的執行結果就爲true,從而不會返回執行onTouchEvent(ev),若是這裏返回false,那麼最終會返回執行onTouchEvent方法,由此可知,接下來要調用的就是onTouchEvent方法了。

可是這裏須要注意一點,若是你不執行super.dispatchTouchEvent()方法,那麼不管你選擇返回false仍是true,該觸摸事件都將不會傳遞下去,通常沒有人會這麼作的,由於Activity你沒有必要不傳遞下去吧。

此次的點擊區域是中間的圖片,我已經在他的父容器的InterceptouchEvent方法中設置了返回值爲true,所以將會攔截事件,也就是說在向下傳遞的過程當中,傳遞到他的外層MyLinearLaytout就將中止傳遞,觸發這一層的onTouch事件,而後返回向外傳遞。輸出結果以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MainActivity---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MyLinearLayout---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MyLinearLayout---onInterceptTouchEvent---ACTION_DOWN
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MyLinearLayout---onInterceptTouchEvent---result: true
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MyLinearLayout---onTouchEvent---ACTION_DOWN
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MyLinearLayout---onTouchEvent---result: false
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MyLinearLayout---dispatchTouchEvent---result: false
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MainActivity---onTouchEvent---ACTION_DOWN
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MainActivity---onTouchEvent---result: false
03 - 20 21 : 20 : 41.231 : I/System.out( 7788 ): MainActivity---dispatchTouchEvent---result: false
03 - 20 21 : 20 : 41.241 : I/System.out( 7788 ): MainActivity---dispatchTouchEvent---ACTION_MOVE
03 - 20 21 : 20 : 41.241 : I/System.out( 7788 ): MainActivity---onTouchEvent---ACTION_MOVE
03 - 20 21 : 20 : 41.251 : I/System.out( 7788 ): MainActivity---onTouchEvent---result: false
03 - 20 21 : 20 : 41.251 : I/System.out( 7788 ): MainActivity---dispatchTouchEvent---result: false
03 - 20 21 : 20 : 41.261 : I/System.out( 7788 ): MainActivity---dispatchTouchEvent---ACTION_UP
03 - 20 21 : 20 : 41.261 : I/System.out( 7788 ): MainActivity---onTouchEvent---ACTION_UP
03 - 20 21 : 20 : 41.261 : I/System.out( 7788 ): MainActivity---onTouchEvent---result: false
03 - 20 21 : 20 : 41.261 : I/System.out( 7788 ): MainActivity---dispatchTouchEvent---result: false

若是不進行攔截,輸出以下,能夠發現,圖片能夠被觸發,而且在MyLinearLayout中的直接子容器MyRelativeLayout也成功觸發

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MainActivity---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyLinearLayout---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyLinearLayout---onInterceptTouchEvent---ACTION_DOWN
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyLinearLayout---onInterceptTouchEvent---result: false
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyRelativeLayout---onInterceptTouchEvent--> false
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyImageView---onTouchEvent---ACTION_DOWN
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyRelativeLayout---dispatchTouchEvent--> true
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyRelativeLayout---onInterceptTouchEvent--> false
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---ACTION_DOWN
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyImageView---onTouchEvent---ACTION_DOWN
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MyLinearLayout---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.947 : I/System.out( 8805 ): MainActivity---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MainActivity---dispatchTouchEvent---ACTION_MOVE
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyLinearLayout---dispatchTouchEvent---ACTION_MOVE
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyLinearLayout---onInterceptTouchEvent---ACTION_MOVE
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyLinearLayout---onInterceptTouchEvent---result: false
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyRelativeLayout---onInterceptTouchEvent--> false
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---ACTION_MOVE
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyImageView---onTouchEvent---ACTION_MOVE
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyRelativeLayout---dispatchTouchEvent--> true
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyRelativeLayout---onInterceptTouchEvent--> false
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---ACTION_MOVE
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyImageView---onTouchEvent---ACTION_MOVE
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MyLinearLayout---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.957 : I/System.out( 8805 ): MainActivity---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MainActivity---dispatchTouchEvent---ACTION_UP
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyLinearLayout---dispatchTouchEvent---ACTION_UP
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyLinearLayout---onInterceptTouchEvent---ACTION_UP
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyLinearLayout---onInterceptTouchEvent---result: false
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyRelativeLayout---onInterceptTouchEvent--> false
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---ACTION_UP
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyImageView---onTouchEvent---ACTION_UP
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyImageView---dispatchTouchEvent---result: true
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyRelativeLayout---dispatchTouchEvent--> true
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyRelativeLayout---onTouchEvent--> false
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MyLinearLayout---dispatchTouchEvent---result: false
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MainActivity---onTouchEvent---ACTION_UP
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MainActivity---onTouchEvent---result: false
03 - 20 21 : 25 : 46.977 : I/System.out( 8805 ): MainActivity---dispatchTouchEvent---result: false

注意上述輸出,若是要看的順利一些,分類看,好比你要看分發的前後觸發順序,就只看有dispatchTouchEvent的輸出,不過的確有點亂,下次再整理一下。

總結:

1.Android的事件傳遞機制,是從最外層到最內曾再到最外層的傳遞過程,換句話說就是從Activity到ViewGroup最後到View的過程,當被其中某一層攔截的時候,將會在該層觸發onTouchEvent事件,而且不會繼續向下級傳遞,而是返回向上傳遞。
2.事件傳遞方法包括dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent,其中前兩個是View和ViewGroup都有的,最後一個是隻有ViewGroup纔有的方法。這三個方法的做用分別是負責事件分發、事件處理、事件攔截。

最後說一下Activity和View的關係:

  1. activity至關於控制部分,view至關於顯示部分。二者之間是多對多的關係,全部東西必須用view來顯示。viewGroup繼承自view,實現了ViewManager,ViewParent接口,主要用做layout方面。
  2. Activity中加載相應的view才能顯示出畫面來,view是具體的畫面佈局(layout),由wegit控件組成。比如view是jsp實現前臺畫面,activity是java程序,處理具體業務邏輯
  3. 基本上每一個activity都有對應的view,activity用於控制view中的響應,如button的點擊事件等能夠在activity中實現,可是你得把這個button給用戶看到啊,因此就用view現實了~
  4. activity就是一個容器,view只能在這個container裏才能正常工做。
  5. Activity主要是控制部分;View主要負責顯示界面

對完整工程有興趣的朋友,歡迎前往本文首發地址 http://jackyonline.org  留言交流,也可在這裏留言~~很是感謝!

相關文章
相關標籤/搜索