Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android的事件機制

Android的事件機制

編輯:關於Android編程

一、理論概述

最基本的操作類型:

down 手指按下 move 手指在屏幕上移動 up 手指從屏幕上離開

觸屏操作的順序:down->move->move->…->up

對屏幕的任一操作,系統都會產生一個MotionEvent對象來對應這個對象。

注:點擊和長按可以同時滿足,如果只想滿足長按,則讓長按的監聽返回true。點擊和長按時可以move。

二、相關API

1、MotionEvent:觸發事件

int ACTION_DOWN = 0 : 代表down int ACTION_MOVE = 2 : 代表move int ACTION_UP = 1 : 代表up getAction() : 得到事件類型 getX() : 得到事件發生的X軸的坐標(相對於當前視圖) getRawX() : 得到事件發生的X軸的坐標(相對於屏幕左頂點) getY() : 得到事件發生的Y軸的坐標(相對於當前視圖) getRawY() : 得到事件發生的Y軸的坐標(相對於屏幕左頂點)

2、Activity

boolean dispatchTouchEvent(MotionEvent event) : 分發事件 boolean onTouchEvent(MotionEvent event) : 處理事件的回調(當沒有子View消費時才調用該方法)

3、View

boolean dispatchTouchEvent(MotionEvent event) : 分發事件(沒有子view,用來決定是使用onTouchEvent還是setOnTouchListener) boolean onTouchEvent(MotionEvent event) : 處理事件的回調方法 void setOnTouchListener(OnTouchListener listener) : 設置事件監聽器 void setOnClickListener(OnClickListener l) void setOnLongClickListener(OnClickListener l) void setOnCreateContextMenuListener(OnCreateContextMenuListener l) 用於創建菜單監聽

4、ViewGroup

boolean dispatchTouchEvent(MotionEvent event) : 分發事件 boolean onInterceptTouchEvent(MotionEvent event) : 攔截事件的回調方法

注:這裡引入兩個概念:處理和消費
只要調用了方法就叫做處理了;
只有返回了true才叫消費了;

事件對象被系統創建後,首先會調用對應Activity的dispatchTouchEvent()進行分發;

down在分發給視圖對象的過程中要確定消費者(onTouchEvent()返回true),如果都返回false,那事件的消費者只能是activity了。

後面的move和up都將分發給消費者(可能是視圖對象,也可能是消費者)

當前事件的消費者只是決定了下一個事件優先交給他處理

每個事件都需要有一個消費者

例子:

MotionEventActivity.java

package com.cwenhui.motionevent;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.cwenhui.test.R;

/**
 * Created by cwenhui on 2016.02.23
 */
public class MotionEventActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_motionevent);

        findViewById(R.id.myImageview).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.e("MotionEventActivity", "setOnTouchListener");
                return false;
            }
        });
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.e("MotionEventActivity", "dispatchTouchEvent--"+ev.getAction());
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("MotionEventActivity", "onTouchEvent--"+event.getAction());
        return super.onTouchEvent(event);
    }
}

layout_motionevent.xml:




    

    

MyImageview.java

package com.cwenhui.motionevent;

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

/**
 * Created by cwenhui on 2016.02.23
 */
public class MyImageView extends ImageView {
    public MyImageView(Context context) {
        super(context);
    }

    public MyImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.e("MyImageView", "MyImageView");
    }

    public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.e("MyImageView", "dispatchTouchEvent--"+event.getAction());
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.e("MyImageView", "onTouchEvent--"+event.getAction());
        return super.onTouchEvent(event)/*true*/;
    }
}

運行分析:
運行結果

如果點擊圖片並滑動,則

09-20 03:20:37.674 25085-25085/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--0
09-20 03:20:37.674 25085-25085/com.cwenhui.test E/MyImageView: dispatchTouchEvent--0
09-20 03:20:37.674 25085-25085/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 03:20:37.674 25085-25085/com.cwenhui.test E/MyImageView: onTouchEvent--0
09-20 03:20:37.674 25085-25085/com.cwenhui.test E/MotionEventActivity: onTouchEvent--0
09-20 03:20:37.708 25085-25085/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:20:37.708 25085-25085/com.cwenhui.test E/MotionEventActivity: onTouchEvent--2
09-20 03:20:37.724 25085-25085/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:20:37.724 25085-25085/com.cwenhui.test E/MotionEventActivity: onTouchEvent--2
09-20 03:20:37.741 25085-25085/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:20:37.741 25085-25085/com.cwenhui.test E/MotionEventActivity: onTouchEvent--2
09-20 03:20:37.758 25085-25085/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:20:37.758 25085-25085/com.cwenhui.test E/MotionEventActivity: onTouchEvent--2
09-20 03:20:37.774 25085-25085/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:20:37.774 25085-25085/com.cwenhui.test E/MotionEventActivity: onTouchEvent--2
09-20 03:20:37.802 25085-25085/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--1
09-20 03:20:37.802 25085-25085/com.cwenhui.test E/MotionEventActivity: onTouchEvent--1

如果將MyImageview.java中的onTouchEvent(MotionEvent event)返回值改為true,則

09-20 03:22:16.122 2077-2077/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--0
09-20 03:22:16.122 2077-2077/com.cwenhui.test E/MyImageView: dispatchTouchEvent--0
09-20 03:22:16.122 2077-2077/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 03:22:16.122 2077-2077/com.cwenhui.test E/MyImageView: onTouchEvent--0
09-20 03:22:16.174 2077-2077/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:22:16.174 2077-2077/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 03:22:16.174 2077-2077/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 03:22:16.174 2077-2077/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 03:22:16.191 2077-2077/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:22:16.191 2077-2077/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 03:22:16.191 2077-2077/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 03:22:16.191 2077-2077/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 03:22:16.208 2077-2077/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:22:16.208 2077-2077/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 03:22:16.208 2077-2077/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 03:22:16.208 2077-2077/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 03:22:16.224 2077-2077/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 03:22:16.224 2077-2077/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 03:22:16.224 2077-2077/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 03:22:16.224 2077-2077/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 03:22:16.279 2077-2077/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--1
09-20 03:22:16.279 2077-2077/com.cwenhui.test E/MyImageView: dispatchTouchEvent--1
09-20 03:22:16.279 2077-2077/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 03:22:16.279 2077-2077/com.cwenhui.test E/MyImageView: onTouchEvent--1

如果此時MotionEventActivity中的OnTouchListener的onTouch()方法返回true,如下:

findViewById(R.id.myImageview).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.e("MotionEventActivity", "setOnTouchListener--"+event.getAction());
                return true;
            }
        });

運行結果如下:

09-20 15:01:53.068 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--0
09-20 15:01:53.068 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--0
09-20 15:01:53.068 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 15:01:53.105 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 15:01:53.105 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 15:01:53.105 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 15:01:53.122 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 15:01:53.122 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 15:01:53.122 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 15:01:53.138 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 15:01:53.139 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 15:01:53.139 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 15:01:53.155 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 15:01:53.155 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 15:01:53.155 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 15:01:53.172 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 15:01:53.172 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 15:01:53.172 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 15:01:53.189 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 15:01:53.189 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 15:01:53.189 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 15:01:53.237 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 15:01:53.237 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 15:01:53.237 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener
09-20 15:01:53.237 3767-3767/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--1
09-20 15:01:53.237 3767-3767/com.cwenhui.test E/MyImageView: dispatchTouchEvent--1
09-20 15:01:53.237 3767-3767/com.cwenhui.test E/MotionEventActivity: setOnTouchListener

可見,沒有執行MyImageview的onTouchEvent(MotionEvent event)方法了。

如果改成手指按下時返回true,即

findViewById(R.id.myImageview).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.e("MotionEventActivity", "setOnTouchListener--"+event.getAction());
//                return false;
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    return true;
                }

                return false;
            }
        });

結果為:

09-20 16:30:48.573 16591-16591/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--0
09-20 16:30:48.573 16591-16591/com.cwenhui.test E/MyImageView: dispatchTouchEvent--0
09-20 16:30:48.573 16591-16591/com.cwenhui.test E/MotionEventActivity: setOnTouchListener--0
09-20 16:30:48.605 16591-16591/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 16:30:48.605 16591-16591/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 16:30:48.605 16591-16591/com.cwenhui.test E/MotionEventActivity: setOnTouchListener--2
09-20 16:30:48.605 16591-16591/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 16:30:48.622 16591-16591/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 16:30:48.622 16591-16591/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 16:30:48.622 16591-16591/com.cwenhui.test E/MotionEventActivity: setOnTouchListener--2
09-20 16:30:48.622 16591-16591/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 16:30:48.638 16591-16591/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 16:30:48.639 16591-16591/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 16:30:48.639 16591-16591/com.cwenhui.test E/MotionEventActivity: setOnTouchListener--2
09-20 16:30:48.639 16591-16591/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 16:30:48.655 16591-16591/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 16:30:48.655 16591-16591/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 16:30:48.655 16591-16591/com.cwenhui.test E/MotionEventActivity: setOnTouchListener--2
09-20 16:30:48.655 16591-16591/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 16:30:48.672 16591-16591/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 16:30:48.672 16591-16591/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 16:30:48.672 16591-16591/com.cwenhui.test E/MotionEventActivity: setOnTouchListener--2
09-20 16:30:48.672 16591-16591/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 16:30:48.689 16591-16591/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--2
09-20 16:30:48.689 16591-16591/com.cwenhui.test E/MyImageView: dispatchTouchEvent--2
09-20 16:30:48.689 16591-16591/com.cwenhui.test E/MotionEventActivity: setOnTouchListener--2
09-20 16:30:48.689 16591-16591/com.cwenhui.test E/MyImageView: onTouchEvent--2
09-20 16:30:48.717 16591-16591/com.cwenhui.test E/MotionEventActivity: dispatchTouchEvent--1
09-20 16:30:48.717 16591-16591/com.cwenhui.test E/MyImageView: dispatchTouchEvent--1
09-20 16:30:48.718 16591-16591/com.cwenhui.test E/MotionEventActivity: setOnTouchListener--1
09-20 16:30:48.718 16591-16591/com.cwenhui.test E/MyImageView: onTouchEvent--1

可見down的時候,事件對象是給OnTouchListener消費了;
move和up時,事件對象給OnTouch消費了。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved