android中Touch事件的處理邏輯 – Android移動開發技術文章_手機開發 Android移動開發教學課程

android中的事件類型分為按鍵事件和屏幕觸摸事件,Touch事件是屏幕觸摸事件的基礎事件,有必要對它進行深入的瞭解。
一個最簡單的屏幕觸摸動作觸發瞭一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE…->ACTION_MOVE->ACTION_UP
當屏幕中包含一個ViewGroup,而這個ViewGroup又包含一個子view,這個時候android系統如何處理Touch事件呢?到底是ViewGroup來處理Touch事件,還是子view來處理Touch事件呢?我隻能很肯定的對你說不一定。呵呵,為什麼呢?看看下面我的調查結果你就明白瞭。
android系統中的每個View的子類都具有下面三個和TouchEvent處理密切相關的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev)  這個方法用來分發TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 這個方法用來攔截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 這個方法用來處理TouchEvent


當TouchEvent發生時,首先Activity將TouchEvent傳遞給最頂層的View, TouchEvent最先到達最頂層 view 的 dispatchTouchEvent ,然後由  dispatchTouchEvent 方法進行分發,如果dispatchTouchEvent返回true ,則交給這個view的onTouchEvent處理,如果dispatchTouchEvent返回 false ,則交給這個 view 的 interceptTouchEvent 方法來決定是否要攔截這個事件,如果 interceptTouchEvent 返回 true ,也就是攔截掉瞭,則交給它的 onTouchEvent 來處理,如果 interceptTouchEvent 返回 false ,那麼就傳遞給子 view ,由子 view 的 dispatchTouchEvent 再來開始這個事件的分發。如果事件傳遞到某一層的子 view 的 onTouchEvent 上瞭,這個方法返回瞭 false ,那麼這個事件會從這個 view 往上傳遞,都是 onTouchEvent 來接收。而如果傳遞到最上面的 onTouchEvent 也返回 false 的話,這個事件就會“消失”,而且接收不到下一次事件。
通過語言描述這個處理邏輯很抽象,下面我就用代碼來具體說明一下。
layout配置文件 main.xml
<?xml version=”1.0″ encoding=”utf-8″?>
<test.lzqdiy.MyLinearLayout xmlns:android=”http://schemas.android.com/apk/res/android”
    android:orientation=”vertical”
    android:layout_width=”fill_parent”
    android:layout_height=”fill_parent”
    android:gravity=”center” >
       <test.lzqdiy.MyTextView
            android:layout_width=”200px”
            android:layout_height=”200px”
            android:id=”@+id/tv”
            android:text=”lzqdiy”
            android:textSize=”40sp”
            android:textStyle=”bold”
            android:background=”#FFFFFF”
            android:textColor=”#0000FF”/>
</test.lzqdiy.MyLinearLayout>
節點層次很簡單,一個LinearLayout中添加瞭一個TextView。
下面是java代碼:
package test.lzqdiy;


import android.app.Activity;
import android.os.Bundle;


public class TestTouchEventApp extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}
package test.lzqdiy;


import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;


public class MyLinearLayout extends LinearLayout {
    private final String TAG = “MyLinearLayout”;


    public MyLinearLayout(Context context, AttributeSet attrs) {


        super(context, attrs);


        Log.d(TAG, TAG);


    }


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        int action = ev.getAction();


        switch (action) {


        case MotionEvent.ACTION_DOWN:


            Log.d(TAG, “dispatchTouchEvent action:ACTION_DOWN”);


            break;


        case MotionEvent.ACTION_MOVE:


            Log.d(TAG, “dispatchTouchEvent action:ACTION_MOVE”);


            break;


        case MotionEvent.ACTION_UP:


            Log.d(TAG, “dispatchTouchEvent action:ACTION_UP”);


            break;


        case MotionEvent.ACTION_CANCEL:


            Log.d(TAG, “dispatchTouchEvent action:ACTION_CANCEL”);


            break;


        }
        return super.dispatchTouchEvent(ev);
    }


    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {


        int action = ev.getAction();


        switch (action) {


        case MotionEvent.ACTION_DOWN:


            Log.d(TAG, “onInterceptTouchEvent action:ACTION_DOWN”);


            break;


        case MotionEvent.ACTION_MOVE:


            Log.d(TAG, “onInterceptTouchEvent action:ACTION_MOVE”);


            break;


        case MotionEvent.ACTION_UP:


            Log.d(TAG, “onInterceptTouchEvent action:ACTION_UP”);


            break;


        case MotionEvent.ACTION_CANCEL:


            Log.d(TAG, “onInterceptTouchEvent action:ACTION_CANCEL”);


            break;


        }


        return false;


    }


    @Override
    public boolean onTouchEvent(MotionEvent ev) {


        int action = ev.getAction();


        switch (action) {


        case MotionEvent.ACTION_DOWN:


            Log.d(TAG, “—onTouchEvent action:ACTION_DOWN”);


            break;


        case MotionEvent.ACTION_MOVE:


    

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *