Android鍵盤和觸摸事件處理
activity和VIEW都能接收觸摸和按鍵,如果響應事件只需要在繼承類里復寫事件函數即可
但是對於VIEW來說,我們如果不改變DRAW,不需要繼承,所以如果想響應事件,則需要
當一個視圖(如一個按鈕)被觸摸時,該對象上的 onTouchEvent() 方法會被調用。不過,為了偵聽這個事件,你必須擴展這個類並重寫該方法。很明顯,擴展每個你想使用的視圖對象(只是處理一個事件)是荒唐的。這就是為什么視圖類也包含了一個嵌套接口的集合,這些接口含有實現起來簡單得多的回調函數。這些接口叫做事件偵聽器 event listeners ,是用來截獲用戶和你的界面交互動作的“門票”。
1.只有一個ACTIVITY得情況:
當鼠標鍵按下時(即觸摸)
首先觸發dispatchTouchEvent
然后觸發onUserInteraction
再次onTouchEvent
如果是點擊的話,緊跟着下列事件(點擊分倆步,ACTION_DOWN,ACTION_up)
觸發dispatchTouchEvent
再次onTouchEvent
當ACTION_up事件時不會觸發onUserInteraction(可查看源代碼)
當鍵盤按下時
首先觸發dispatchKeyEvent
然后觸發onUserInteraction
再次onKeyDown
如果按下緊接着松開,則是倆步
緊跟着觸發dispatchKeyEvent
然后觸發onUserInteraction
再次onKeyUp
注意與觸摸不同,當松開按鍵時onUserInteraction也會觸發。
Activity.dispatchTouchEvent(MotionEvent) - 這允許你的活動可以在分發給窗口之前捕獲所有的觸摸事件。
(同理 dispatchKeyEvent)
onUserInteraction :Called whenever a key, touch, or trackball event is dispatched to the
* activity.
2.activity里有一個LAYOUT,在布局里有個按鈕。
如果在按鈕上觸發一個CLICK事件
首先觸發ACTIVITY的dispatchTouchEvent
然后觸發ACTIVITY的onUserInteraction
然后觸發LAYOUT的dispatchTouchEvent
然后觸發LAYOUT的onInterceptTouchEvent
然后觸發BUTTON的onTouch(這是一個ACTION_DOWN事件)
緊跟着是一個ACTION_UP事件
觸發ACTIVITY的dispatchTouchEvent
注意不再觸發ACTIVITY的onUserInteraction,因為他對ACTION_UP不起作用。
然后觸發LAYOUT的dispatchTouchEvent
然后觸發LAYOUT的onInterceptTouchEvent
然后觸發BUTTON的onTouch
最后觸發BUTTON的onClick.
如果你在ONTOUCH事件里返回true,消費了此事件,那么ONCLICK將不會被響應
但是如果你不寫ONCLICK事件,而ONTOUCH事件返回FLASE
那么最終事件序列:
11-23 17:19:44.313: INFO/activity(803): dispatchTouchEvent
11-23 17:19:44.313: INFO/activity(803): onUserInteraction
11-23 17:19:44.322: INFO/LinearLayout(803): dispatchTouchEvent
11-23 17:19:44.333: INFO/LinearLayout(803): onInterceptTouchEvent
11-23 17:19:44.341: INFO/button(803): onTouch
11-23 17:19:44.441: INFO/activity(803): dispatchTouchEvent
11-23 17:19:44.451: INFO/LinearLayout(803): dispatchTouchEvent
11-23 17:19:44.451: INFO/LinearLayout(803): onInterceptTouchEvent
11-23 17:19:44.461: INFO/button(803): onTouch
即事件不會再向上傳遞,估計是ONCLICK有默認響應不處理,而ONCLICK不會有返回值。
但是如果是繼承了一個VIEW而且又覆寫了onTouchEvent,他返回FALSE
當觸摸事件發生時
11-23 17:25:59.691: INFO/activity(831): dispatchTouchEvent
11-23 17:25:59.691: INFO/activity(831): onUserInteraction
11-23 17:25:59.701: INFO/LinearLayout(831): dispatchTouchEvent
11-23 17:25:59.701: INFO/LinearLayout(831): onInterceptTouchEvent
11-23 17:25:59.701: INFO/button(831): onTouch
11-23 17:25:59.701: INFO/Button(831): onTouchEvent
11-23 17:25:59.701: INFO/LinearLayout(831): onTouchEvent
11-23 17:25:59.701: INFO/activity(831): onTouchEvent
11-23 17:25:59.822: INFO/activity(831): dispatchTouchEvent
11-23 17:25:59.822: INFO/activity(831): onTouchEvent
奇怪的是,ONCLICK事件不再發生。
VIEW和ACTIVITY本身都有相應鍵盤事件的ONKEYUP和ONKEYDOWN
對於VIEW來說,你可以setOnKeyListener(new OnKeyListener(){
@Override
public boolean onKey(
來響應鍵盤事件,如果你既對VIEW寫了這個偵聽,又覆寫了ONKEYUP,DOWN事件,那么首先
進入ONKEY
比如用反向鍵把焦點切換到按鈕上
事件序列:
11-23 17:23:14.392: INFO/activity(803): dispatchKeyEvent
11-23 17:23:14.404: INFO/activity(803): onUserInteraction
11-23 17:23:14.412: INFO/LinearLayout(803): dispatchKeyEvent
11-23 17:23:14.412: INFO/button(803): onKey
11-23 17:23:14.422: INFO/activity(803): onKeyUp
當按回車時
11-23 17:35:55.692: INFO/activity(831): dispatchKeyEvent
11-23 17:35:55.713: INFO/activity(831): onUserInteraction
11-23 17:35:55.722: INFO/LinearLayout(831): dispatchKeyEvent
11-23 17:35:55.732: INFO/button(831): onKey
11-23 17:35:55.813: INFO/activity(831): dispatchKeyEvent
11-23 17:35:55.824: INFO/activity(831): onUserInteraction
11-23 17:35:55.831: INFO/LinearLayout(831): dispatchKeyEvent
11-23 17:35:55.831: INFO/button(831): onKey
11-23 17:35:55.953: INFO/button(831): onClick
最后補充下:不需要那么復雜,如果對於控件想響應他的觸摸事件,如果繼承
則覆寫ONTOUCHEVENT,如果不覆寫則偵聽ONTOUCH
如果覆寫了ONTOUCHEVENT,則不再響應ONCLICK事件
如果寫了ONCLICK,則不要再搞ONTOUCHEVENT了
所以ONCLICK和ONTOUCHEVENT二取一,另外如果有ONTOUCH偵聽,那么此函數要先於其他函數執行
對於ONCLICK來說,要從頭走倆便ONTOUCH,一次是DOWN,一次是UP
同樣的對於ONKEY,以及ONKEYUP和DOWN
如果既覆寫了ONKEYUODOWN,又SET了偵聽ONKEY,那么ONKEY要優先執行,對於一個回車按鍵觸發時
11-24 09:55:18.601: INFO/activity(951): dispatchKeyEvent
11-24 09:55:18.611: INFO/activity(951): onUserInteraction
11-24 09:55:18.621: INFO/LinearLayout(951): dispatchKeyEvent
11-24 09:55:18.641: INFO/button(951): onKey
11-24 09:55:18.711: INFO/activity(951): dispatchKeyEvent
11-24 09:55:18.756: INFO/activity(951): onUserInteraction
11-24 09:55:18.775: INFO/LinearLayout(951): dispatchKeyEvent
11-24 09:55:18.791: INFO/button(951): onKey
11-24 09:55:18.822: INFO/button(951): onClick
但是對於VIEW來說,我們如果不改變DRAW,不需要繼承,所以如果想響應事件,則需要
當一個視圖(如一個按鈕)被觸摸時,該對象上的 onTouchEvent() 方法會被調用。不過,為了偵聽這個事件,你必須擴展這個類並重寫該方法。很明顯,擴展每個你想使用的視圖對象(只是處理一個事件)是荒唐的。這就是為什么視圖類也包含了一個嵌套接口的集合,這些接口含有實現起來簡單得多的回調函數。這些接口叫做事件偵聽器 event listeners ,是用來截獲用戶和你的界面交互動作的“門票”。
1.只有一個ACTIVITY得情況:
當鼠標鍵按下時(即觸摸)
首先觸發dispatchTouchEvent
然后觸發onUserInteraction
再次onTouchEvent
如果是點擊的話,緊跟着下列事件(點擊分倆步,ACTION_DOWN,ACTION_up)
觸發dispatchTouchEvent
再次onTouchEvent
當ACTION_up事件時不會觸發onUserInteraction(可查看源代碼)
當鍵盤按下時
首先觸發dispatchKeyEvent
然后觸發onUserInteraction
再次onKeyDown
如果按下緊接着松開,則是倆步
緊跟着觸發dispatchKeyEvent
然后觸發onUserInteraction
再次onKeyUp
注意與觸摸不同,當松開按鍵時onUserInteraction也會觸發。
Activity.dispatchTouchEvent(MotionEvent) - 這允許你的活動可以在分發給窗口之前捕獲所有的觸摸事件。
(同理 dispatchKeyEvent)
onUserInteraction :Called whenever a key, touch, or trackball event is dispatched to the
* activity.
2.activity里有一個LAYOUT,在布局里有個按鈕。
如果在按鈕上觸發一個CLICK事件
首先觸發ACTIVITY的dispatchTouchEvent
然后觸發ACTIVITY的onUserInteraction
然后觸發LAYOUT的dispatchTouchEvent
然后觸發LAYOUT的onInterceptTouchEvent
然后觸發BUTTON的onTouch(這是一個ACTION_DOWN事件)
緊跟着是一個ACTION_UP事件
觸發ACTIVITY的dispatchTouchEvent
注意不再觸發ACTIVITY的onUserInteraction,因為他對ACTION_UP不起作用。
然后觸發LAYOUT的dispatchTouchEvent
然后觸發LAYOUT的onInterceptTouchEvent
然后觸發BUTTON的onTouch
最后觸發BUTTON的onClick.
如果你在ONTOUCH事件里返回true,消費了此事件,那么ONCLICK將不會被響應
但是如果你不寫ONCLICK事件,而ONTOUCH事件返回FLASE
那么最終事件序列:
11-23 17:19:44.313: INFO/activity(803): dispatchTouchEvent
11-23 17:19:44.313: INFO/activity(803): onUserInteraction
11-23 17:19:44.322: INFO/LinearLayout(803): dispatchTouchEvent
11-23 17:19:44.333: INFO/LinearLayout(803): onInterceptTouchEvent
11-23 17:19:44.341: INFO/button(803): onTouch
11-23 17:19:44.441: INFO/activity(803): dispatchTouchEvent
11-23 17:19:44.451: INFO/LinearLayout(803): dispatchTouchEvent
11-23 17:19:44.451: INFO/LinearLayout(803): onInterceptTouchEvent
11-23 17:19:44.461: INFO/button(803): onTouch
即事件不會再向上傳遞,估計是ONCLICK有默認響應不處理,而ONCLICK不會有返回值。
但是如果是繼承了一個VIEW而且又覆寫了onTouchEvent,他返回FALSE
當觸摸事件發生時
11-23 17:25:59.691: INFO/activity(831): dispatchTouchEvent
11-23 17:25:59.691: INFO/activity(831): onUserInteraction
11-23 17:25:59.701: INFO/LinearLayout(831): dispatchTouchEvent
11-23 17:25:59.701: INFO/LinearLayout(831): onInterceptTouchEvent
11-23 17:25:59.701: INFO/button(831): onTouch
11-23 17:25:59.701: INFO/Button(831): onTouchEvent
11-23 17:25:59.701: INFO/LinearLayout(831): onTouchEvent
11-23 17:25:59.701: INFO/activity(831): onTouchEvent
11-23 17:25:59.822: INFO/activity(831): dispatchTouchEvent
11-23 17:25:59.822: INFO/activity(831): onTouchEvent
奇怪的是,ONCLICK事件不再發生。
VIEW和ACTIVITY本身都有相應鍵盤事件的ONKEYUP和ONKEYDOWN
對於VIEW來說,你可以setOnKeyListener(new OnKeyListener(){
@Override
public boolean onKey(
來響應鍵盤事件,如果你既對VIEW寫了這個偵聽,又覆寫了ONKEYUP,DOWN事件,那么首先
進入ONKEY
比如用反向鍵把焦點切換到按鈕上
事件序列:
11-23 17:23:14.392: INFO/activity(803): dispatchKeyEvent
11-23 17:23:14.404: INFO/activity(803): onUserInteraction
11-23 17:23:14.412: INFO/LinearLayout(803): dispatchKeyEvent
11-23 17:23:14.412: INFO/button(803): onKey
11-23 17:23:14.422: INFO/activity(803): onKeyUp
當按回車時
11-23 17:35:55.692: INFO/activity(831): dispatchKeyEvent
11-23 17:35:55.713: INFO/activity(831): onUserInteraction
11-23 17:35:55.722: INFO/LinearLayout(831): dispatchKeyEvent
11-23 17:35:55.732: INFO/button(831): onKey
11-23 17:35:55.813: INFO/activity(831): dispatchKeyEvent
11-23 17:35:55.824: INFO/activity(831): onUserInteraction
11-23 17:35:55.831: INFO/LinearLayout(831): dispatchKeyEvent
11-23 17:35:55.831: INFO/button(831): onKey
11-23 17:35:55.953: INFO/button(831): onClick
最后補充下:不需要那么復雜,如果對於控件想響應他的觸摸事件,如果繼承
則覆寫ONTOUCHEVENT,如果不覆寫則偵聽ONTOUCH
如果覆寫了ONTOUCHEVENT,則不再響應ONCLICK事件
如果寫了ONCLICK,則不要再搞ONTOUCHEVENT了
所以ONCLICK和ONTOUCHEVENT二取一,另外如果有ONTOUCH偵聽,那么此函數要先於其他函數執行
對於ONCLICK來說,要從頭走倆便ONTOUCH,一次是DOWN,一次是UP
同樣的對於ONKEY,以及ONKEYUP和DOWN
如果既覆寫了ONKEYUODOWN,又SET了偵聽ONKEY,那么ONKEY要優先執行,對於一個回車按鍵觸發時
11-24 09:55:18.601: INFO/activity(951): dispatchKeyEvent
11-24 09:55:18.611: INFO/activity(951): onUserInteraction
11-24 09:55:18.621: INFO/LinearLayout(951): dispatchKeyEvent
11-24 09:55:18.641: INFO/button(951): onKey
11-24 09:55:18.711: INFO/activity(951): dispatchKeyEvent
11-24 09:55:18.756: INFO/activity(951): onUserInteraction
11-24 09:55:18.775: INFO/LinearLayout(951): dispatchKeyEvent
11-24 09:55:18.791: INFO/button(951): onKey
11-24 09:55:18.822: INFO/button(951): onClick