(二十五)touch事件消息傳遞

一、android 事件分發是先傳遞到ViewGroup,再由ViewGroup傳遞到View的。android

二、在ViewGroup中能夠經過onInterceptTouchEvent方法對事件傳遞進行攔截,onInterceptTouchEvent方法返回true表明不容許事件繼續向子View傳遞, 返回false表明不對事件攔截。ide

三、子View中若是將傳遞的事件消費掉,ViewGroup將沒法接收到任何事件。spa

四、super.onInterceptTouchEvent(ev)默認爲FALSE3d

五、事件傳遞機制的步驟:rest

     5.一、view執行dispatchTouchEvent方法,開始分發事件code

     5.二、執行onInterceptTouchEvent判斷是否中斷事件分發blog

     4.三、執行onTouchEvent方法,去處理事件事件

六、touch事件處理流程圖get

七、多點觸控事件it

在android的中,MotionEvent event表明的是一個觸摸事件。咱們對屏幕的幾乎全部操做都會觸發該事件,如點擊、放開、滑動等。不一樣的事件在MotionEvent中有不一樣的id,根據id的不一樣能夠判斷觸摸事件屬於哪一個手指。

在MotionEvent類中有兩個參數能夠用來獲取對觸摸的控制,這兩個參數分別爲:MotionEvent.getAction()和MotionEvent.ACTION_MASK,前者用於對單點觸控進行操做,後者用於對多點觸控進行操做,相應地,咱們能夠經過Android Developers’ Reference看到,對於單點觸控,咱們由MotionEvent.getAction()能夠獲得如下幾種事件:ACTION_DOWN、ACTION_UP,而對於多點觸控,由MotionEvent.ACTION_MASK,咱們能夠獲得:ACTION_POINTER_DOWN、ACTION_POINTER_UP,都是MotionEvent中的常量,能夠直接調用。而有些常量則是單點和多點共用的,如:ACTION_MOVE,所以在按下時,咱們必須標記單點與多點觸控的區別。

下面將介紹一下上面提到的五個操做:

  • MotionEvent.ACTION_DOWN:在第一個點被按下時觸發
  • MotionEvent.ACTION_UP:當屏幕上惟一的點被放開時觸發
  • MotionEvent.ACTION_POINTER_DOWN:當屏幕上已經有一個點被按住,此時再按下其餘點時觸發。
  • MotionEvent.ACTION_POINTER_UP:當屏幕上有多個點被按住,鬆開其中一個點時觸發(即非最後一個點被放開時)。
  • MotionEvent.ACTION_MOVE:當有點在屏幕上移動時觸發。值得注意的是,因爲它的靈敏度很高,而咱們的手指又不可能徹底靜止(即便咱們感受不到移動,但其實咱們的手指也在不停地抖動),因此實際的狀況是,基本上只要有點在屏幕上,此事件就會一直不停地被觸發。

舉例來說:當咱們放一個食指到屏幕上時,觸發ACTION_DOWN事件;再放一個拇指到屏幕上,觸發ACTION_POINTER_DOWN事件;此時再把食指或拇指放開,都會觸發ACTION_POINTER_UP事件;再放開最後一個手指,觸發ACTION_UP事件;而同時在整個過程當中,ACTION_MOVE事件會一直不停地被觸發。例子代碼以下所示:

/**
 * 多指操做時,爲了不多個事件進行響應,當多個點被按住時,阻止事件向下分發
 * 
 * 
 */
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:   //在第一個點被按下時觸發         
        case MotionEvent.ACTION_UP:        //當屏幕上惟一的點被放開時觸發
        case MotionEvent.ACTION_POINTER_UP:   //當屏幕上有多個點被按住,鬆開其中一個點時觸發(即非最後一個點被放開時)。
            break;
        case MotionEvent.ACTION_POINTER_DOWN:   //當屏幕上已經有一個點被按住,此時再按下其餘點時觸發。
            return true;              //中斷事件向下分發
        }
        return false;               //觸摸事件繼續向下分發
    }

 

八、一個自定義的LinearLayout的代碼

package com.example.pinterestlistview;

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

public class MyLinearLayout extends LinearLayout {


    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;       //中斷事件向下分發
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.i("fuyanan", "yanan:"+super.dispatchTouchEvent(ev));
        return super.dispatchTouchEvent(ev);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        
        int width=getWidth()/getChildCount();
        int height = getHeight();
        int count=getChildCount();
        Log.i("fuyanan", "yanan:"+count);
        float eventX = event.getX();
        
        if (eventX<width){    // 滑動左邊的 listView
            event.setLocation(width/2, event.getY());
            Log.i("fuyanan", "yanan:"+getChildAt(0));
            getChildAt(0).dispatchTouchEvent(event);     //  事件分發給第一個孩子
            return true;
            
        } else if (eventX > width && eventX < 2 * width) { //滑動中間的 listView  
            float eventY = event.getY();
            if (eventY < height / 2) {
                event.setLocation(width / 2, event.getY());
                for (int i = 0; i < count; i++) {
                    View child = getChildAt(i);
                    try {
                        child.dispatchTouchEvent(event);    事件分發給全部的孩子
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    
                }
                return true;
            } else if (eventY > height / 2) {
                event.setLocation(width / 2, event.getY());
                try {
                    getChildAt(1).dispatchTouchEvent(event);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return true;
            }
        }else if (eventX>2*width){
            event.setLocation(width/2, event.getY());
            getChildAt(2).dispatchTouchEvent(event);   事件分發給第三個孩子
            return true;
        }
        
        return true;   //消耗此事件
    }
    
}
相關文章
相關標籤/搜索