閱讀293 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Android——MotionEvent對象分析

當用戶觸摸屏幕時將創建一個MotionEvent對象。MotionEvent包含關於發生觸摸的位置和時間等細節信息。MotionEvent對象被傳遞到程序中合適的方法比如View對象的onTouchEvent()方法中。在這些方法中我們可以分析MotionEvent對象那個,以決定要執行的操作。

   MotionEvent對象是與用戶觸摸相關的時間序列,該序列從用戶首次觸摸屏幕開始,經曆手指在屏幕表麵的任何移動,直到手指離開屏幕時結束。手指的初次觸摸(ACTION_DOWN操作),滑動(ACTION_MOVE操作)和抬起(ACTION_UP)都會創建MotionEvent對象。移動過程中會產生大量事件,每個事件都會產生對應的MotionEvent對象記錄發生的操作,觸摸的位置,使用的多大壓力,觸摸的麵積,合適發生,以及最初的ACTION_DOWN和時發生等相關的信息。

    在設置事件時我們有2設置的方式,一種是委托式一種是回調式。第一種就是將事件的處理委托給監聽器處理,你可以定義一個View.OnTouchListener接口的子類作為監聽器,其中有onTouch()方法。而第二種是重寫View類自己本身的onTouchEvent方法,也就是控件自己處理事件。onTouch方法接收一個MotionEvent參數和一個View參數,而onTouchEvent方法僅接收MotionEvent參數。這是因為監聽器可以監聽多個View控件的事件。無論是通過onTouchEvent還是onTouch方法 它們的返回值都是boolean類型。true的含義是如果當前處理程序在處理完畢該事件後不希望傳播給其他控件,則返回true。如果View對象不但對此事件不感興趣,而且對與此觸摸序列相關的任何未來事件都不感興趣,那麼返回false。比如如果ButtononTouchEvent方法想要處理用戶的一次點擊 則會有2個事件產生ACTION_DOWNACTION_UP,按道理這兩個事件都會調用onTouchEvent方法,如果方法返回false則在按下時你可以做一些操作,但是手指抬起時你將不能再接收到MotionEvent對象了,所以你也就無從處理抬起事件了。

MotionEvent事件在onInterceptTouchEvent()onTouchEvent()中的傳遞順序 

onInterceptTouchEvent()用於處理事件並改變事件的傳遞方向。處理事件這個不用說了,你在函數內部編寫代碼處理就可以了。而決定傳遞方向的是返回值,返回為false時事件會傳遞給子控件的onInterceptTouchEvent();返回值為true時事件會傳遞給當前控件的onTouchEvent(),而不在傳遞給子控件,這就是所謂的Intercept(截斷)
    onTouchEvent() 用於處理事件,返回值決定當前控件是否消費(consume)了這個事件。可能你要問是否消費了又區別嗎,反正我已經針對事件編寫了處理代碼?答案是有區別!比如ACTION_MOVE或者ACTION_UP發生的前提是一定曾經發生了ACTION_DOWN,如果你沒有消費ACTION_DOWN,那麼係統會認為ACTION_DOWN沒有發生過,所以ACTION_MOVE或者ACTION_UP就不能被捕獲。


<?xml version="1.0" encoding="utf-8"?>
<com.touchstudy.LayoutView1 xmlns:androhttps://schemas.android.com/apk/res/android" >https://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <com.touchstudy.LayoutView2
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center">
       <com.touchstudy.MyTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:
            android:text="AB"
            android:textSize="40sp"
            android:textStyle="bold"
            android:background="#FFFFFF"
            android:textColor="#0000FF"/>
   </com.touchstudy.LayoutView2>
</com.touchstudy.LayoutView1>
在沒有重寫onInterceptTouchEvent()onTouchEvent()的情況下(他們的返回值都是false), 對上麵這個布局,MotionEvent事件的傳遞順序如下: 



當某個控件的onInterceptTouchEvent()返回值為true時,就會發生截斷,事件被傳到當前控件的onTouchEvent()。如我們將LayoutView2onInterceptTouchEvent()返回值為true,則傳遞流程變成:


 如果我們同時將LayoutView2onInterceptTouchEvent()onTouchEvent()設置成true,那麼LayoutView2將消費被傳遞的事件,同時後續事件(如跟著ACTION_DOWNACTION_MOVE或者ACTION_UP)會直接傳給LayoutView2onTouchEvent(),不傳給其他任何控件的任何函數。同時傳遞給子空間一個ACTION_CANCEL事件。傳遞流程變成(圖中沒有畫出ACTION_CANCEL事件):

最後更新:2017-04-02 16:48:03

  上一篇:go android ListView中自定義SimpleAdapter動態添加ratingBar及圖片更新
  下一篇:go java在CPU中的一些個破事