Android Touch事件分發機制學習

來源:互聯網
上載者:User

標籤:touch   android   事件   motionevent   

Android中的事件分為按鍵事件和觸摸事件。
Touch事件是由一個ACTION_DOWN,n個ACTION_MOVE,一個ACTION_UP組成onClick,onLongClick,onScroll等事件。
Android 中與 Touch 事件相關的方法及其對應的作用:
dispatchTouchEvent(MotionEvent ev) 事件分發
onInterceptTouchEvent(MotionEvent ev) 事件攔截
onTouchEvent(MotionEvent ev) 事件響應

Activity:dispatchTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev)
View: dispatchTouchEvent(MotionEvent ev)、onTouchEvent(MotionEvent ev)
ViewGroup繼承View,上面方法都是public的,所以他擁有上面所有方法,ViewGroup類裡面新添加了方法onInterceptTouchEvent(MotionEvent ev)。

為了比較清楚的瞭解執行流程,我做了的小demo:

這裡我們要清楚一個東西,控制項分為兩種:一種是繼承View不能包含其他控制項的控制項;另一種是繼承ViewGroup可以包含其他控制項的控制項,暫且稱為容器控制項,比如ListView,GridView,LinearLayout等。
上面demo的Button就是繼承自View的,淺綠色地區是一個橫向的LinearLayout,而他是繼承自ViewGroup的。

先概述一下demo的製作:
裡面有三個類:
MyActivity extends Activity
MyButton extends Button
MyLinearLayout extends LinearLayout
在MyActivity中:

public class MyActivity extends Activity{    private static final String TAG = MyActivity.class.getSimpleName();    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    public boolean dispatchTouchEvent(MotionEvent ev) {        Log.i(TAG, MotionEvent.actionToString(ev.getAction()) + " dispatchTouchEvent()");        return super.dispatchTouchEvent(ev);    }    public boolean onTouchEvent(MotionEvent event) {        Log.i(TAG, MotionEvent.actionToString(event.getAction()) + " onTouchEvent()");        return super.onTouchEvent(event);    }}

MyButton和MyLinearLayout十分相似,MyLinearLayout只多了一個onInterceptTouchEvent方法,這裡貼出MyButton的代碼,如果需要MyLinearLayout的代碼可以在後面直接下載,看完整的代碼。
MyButton

public class MyButton extends Button{    private static final String TAG = MyButton.class.getSimpleName();    public MyButton(Context context)    {        super(context);    }    public MyButton(Context context, AttributeSet attrs)    {        super(context, attrs);    }       public MyButton(Context context, AttributeSet attrs, int defStyleAttr)    {        super(context, attrs, defStyleAttr);        // TODO Auto-generated constructor stub    }    public boolean dispatchTouchEvent(MotionEvent ev) {        Log.i(TAG, MotionEvent.actionToString(ev.getAction()) + " dispatchTouchEvent()");        return super.dispatchTouchEvent(ev);    }    public boolean onTouchEvent(MotionEvent event) {        Log.i(TAG, MotionEvent.actionToString(event.getAction()) + " onTouchEvent()");        return super.onTouchEvent(event);    }}

Java代碼都是非常簡單的
因為我們要使用自己定義的控制項,所以在xml布局代碼中是這樣的:

<per.lee.eventdispatchtest.MyLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="#00FF00"  >    <per.lee.eventdispatchtest.MyButton        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Button" /></per.lee.eventdispatchtest.MyLinearLayout>

log的顯示為 Tag顯示:具體類, Text顯示:具體動作 + 調用方法名

點擊MyButton(深綠色地區),出現的結果是:

點擊MyLinearLayout 非MyButton地區(淺綠色地區),結果是:

點擊MyActivity 非MyLinearLayout地區(空白地區),結果是:

從以上Log可以看出:
一個Touch事件會從外層逐層分發到內層,直到事件處理為止(return true),表面現象分析完畢了,後面我找機會研究一下源碼,內部具體到底是怎麼處理的。

這個小demo的代碼:EventDispatchTest.zip

Android Touch事件分發機制學習

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.