中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android事件流程詳解

發布時間:2020-07-30 14:06:15 來源:網絡 閱讀:413 作者:GeekTrain 欄目:移動開發

Android事件流程詳解

    網絡上有不少博客講述了android的事件分發機制和處理流程機制,但是看過千遍,總還是覺得有些迷迷糊糊,因此特地抽出一天事件來親測下,向像我一樣的廣大入門程序員詳細講述android事件背后的故事,話不多說,上干貨。

    android整個事件流程主要牽扯到dispatchTouchEvent(),onInterceptTouchEvent(),

onTouchEvent()這三個方法,下表來說明這三個方法的功能和分布場景:

    表1:

方法名稱功解解說ActivityViewGroupView
dispatchTouchEvent()事件分發YESYESYES
onInterceptTouchEvent()事件攔截NOYESNO
onTouchEvent()事件處理YESYESYES

  先來分析下Touch事件:所有Touch事件發生時會調用當前Activity的dispatchTouchEvent()方


法來分發事件,Activity的dispatchTouchEvent()方法最終會調用PhoneWindow類中的


superDispatchTouchEvent方法,最終邏輯就是該activity會調用ViewGroup類中的


dispatchTouchEvent()進行隧道式分發事件(按布局元素由外向內分發),如本案例中的分發流程


為TouchTraining    ->  TouchViewGroup -> TouchView,需要注意的是,當你在Activit中的


dispatchTouchEvent()中直接返回具體的布爾值(無論是true還是false),Touch事件直接會被


消費在該方法中,不會再進行下來的事件分發流程,因此必須在activity的dispatchTouchEvrent


返回super.dispatchTouchEvent()來進行事件分發流程。下面進行案例說明分析:


  首先在定義自己的View和ViewGroup,重寫表1它們各自支持的事件流程方法,我這里自定ViewGroup


繼承的是LinearLayout(只要繼承的是ViewGroup都一樣),然后分別在Activity的布局文件中加入自定


義的控件,接著在Activity中也重寫它支持的事件流程方法。


activity_touchtrain.xml

        

Android事件流程詳解


TouchView(自定義View類)

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    Log.e(TAG, "dispatchTouchEvent分發事件"+ TouchEventUtil.getTouchAction(event.getAction()));
    return super.dispatchTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    Log.e(TAG, "onTouchEvent處理事件"+ TouchEventUtil.getTouchAction(ev.getAction()));
    return super.onTouchEvent(ev);
}

TouchViewGroup(自定義ViewGroup類)

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Log.e(TAG, "dispatchTouchEvent分發事件" + TouchEventUtil.getTouchAction(ev.getAction()));
    return super.dispatchTouchEvent(ev);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    Log.e(TAG, "onInterceptTouchEvent攔截事件"+ TouchEventUtil.getTouchAction(ev.getAction()));
    return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    Log.e(TAG, "onTouchEvent處理事件"+ TouchEventUtil.getTouchAction(ev.getAction()));
    return super.onTouchEvent(ev);
}

TouchTraining(Activity)

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    Log.e(TAG, "dispatchTouchEvent分發事件"+ TouchEventUtil.getTouchAction(ev.getAction()));
    return super.dispatchTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    Log.e(TAG, "onTouchEvent處理事件"+ TouchEventUtil.getTouchAction(ev.getAction()));
    return super.onTouchEvent(ev);
}

TouchEventUtils(工具類,獲取當前事件類型)

public static String getTouchAction(int actionId) {
    String actionName = "Unknow:id=" + actionId;
    switch (actionId) {
        case MotionEvent.ACTION_DOWN:
            actionName = "ACTION_DOWN";
            break;
        case MotionEvent.ACTION_MOVE:
            actionName = "ACTION_MOVE";
            break;
        case MotionEvent.ACTION_UP:
            actionName = "ACTION_UP";
            break;
        case MotionEvent.ACTION_CANCEL:
            actionName = "ACTION_CANCEL";
            break;
        case MotionEvent.ACTION_OUTSIDE:
            actionName = "ACTION_OUTSIDE";
            break;
    }
    return actionName;
}


案例分析


方案1

條件
控件名稱dispatchTouchEvent返回值onInterceptTouchEvent 返回值onTouchEvent 返回值
TouchTraining
super.dispatchTouchEvent(ev)----super.onTouchEvent(ev)
TouchViewGroupfalsesuper.onInterceptTouchEvent(ev)super.onTouchEvent(ev)
TouchViewsuper.dispatchTouchEvent(ev)----super.onTouchEvent(ev)

運行結果:

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchTraining: onTouchEvent處理事件ACTION_DOWN

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_UP

com.training.cj.mytraining E/TouchTraining: onTouchEvent處理事件ACTION_UP


結果分析:Touch事件開始,調用TouchTraining的dispatchTouchEvent把事件分發TouchViewGroup

的dispatchTouchEvent,TouchViewGroup的dispatchTouchEvent返回false,事件停止向下傳遞,同

時事件并沒有消費,但由于該事件來自TouchTraining(Activity),所以最終返回給TouchTraining

的onTouchEvent進行消費。


方案2

條件
控件名稱dispatchTouchEvent返回值onInterceptTouchEvent 返回值onTouchEvent 返回值
TouchTraining
super.dispatchTouchEvent(ev)----super.onTouchEvent(ev)
TouchViewGrouptruesuper.onInterceptTouchEvent(ev)super.onTouchEvent(ev)
TouchViewsuper.dispatchTouchEvent(ev)----super.onTouchEvent(ev)

運行結果:

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_UP

com.training.cj.mytraining E/TouchViewGroup: dispatchTouchEvent分發事件ACTION_UP


結果分析:Touch事件由TouchTraining的dispatchTouchEvent不斷向TouchViewGroup分發,

TouchViewGroup的dispatchTouchEvent返回true,TouchViewGroup在dispatchTouchEvent中不斷消

費來自TouchTraining的dispatchTouchEvent分發的事件。


方案3

條件
控件名稱dispatchTouchEvent返回值onInterceptTouchEvent 返回值onTouchEvent 返回值
TouchTraining
super.dispatchTouchEvent(ev)----super.onTouchEvent(ev)
TouchViewGroupsuper.onInterceptTouchEvent(ev)truesuper.onTouchEvent(ev)
TouchViewsuper.dispatchTouchEvent(ev)----super.onTouchEvent(ev)

運行結果:

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: onInterceptTouchEvent攔截事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: onTouchEvent處理事件ACTION_DOWN

com.training.cj.mytraining E/TouchTraining: onTouchEvent處理事件ACTION_DOWN

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_UP

com.training.cj.mytraining E/TouchTraining: onTouchEvent處理事件ACTION_UP


結果分析:Touch事件發生,調用TouchTraining的dispatchTouchEvent分發事件到TouchViewGroup

的dispatchTouchEvent,TouchViewGroup的dispatchTouchEvent返回super.onInterceptTouchEvent(ev)進

行事件分發,事件向下傳遞給TouchViewGroup的onInterceptTouchEvent,TouchViewGroup的onInterceptTouchEvent返回true,事件被攔截并傳遞給TouchViewGroup的onTouchEvent進行消費,TouchViewGroup的onTouchEvent返回super.dispatchTouchEvent(ev),對Touch事件未消費并返回給上級控件的onTouchEvent進行消費,由于TouchViewGroup的Touch事件來自TouchTraining,所以最后 由TouchTraining的onTouchEvent進行消費。


方案4


條件
控件名稱dispatchTouchEvent返回值onInterceptTouchEvent 返回值onTouchEvent 返回值
TouchTraining
super.dispatchTouchEvent(ev)----super.onTouchEvent(ev)
TouchViewGroupsuper.onInterceptTouchEvent(ev)falsesuper.onTouchEvent(ev)
TouchViewsuper.dispatchTouchEvent(ev)----super.onTouchEvent(ev)


運行結果:

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: onInterceptTouchEvent攔截事件ACTION_DOWN

com.training.cj.mytraining E/TouchView: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchView: onTouchEvent處理事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: onTouchEvent處理事件ACTION_DOWN

com.training.cj.mytraining E/TouchTraining: onTouchEvent處理事件ACTION_DOWN

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_UP

com.training.cj.mytraining E/TouchTraining: onTouchEvent處理事件ACTION_UP


結果分析:Touch事件發生,調用TouchTraining的dispatchTouchEvent分發事件到TouchViewGroup的dispatchTouchEvent,TouchViewGroup的dispatchTouchEvent返回super.onInterceptTouchEvent(ev),繼續分發向下傳遞事件到TouchViewGroup的onInterceptTouchEvent,TouchViewGroup的onInterceptTouchEvent返回false,繼續分發向下傳遞事件到TouchView的dispatchTouchEvent,TouchView的dispatchTouchEvent返回super.dispatchTouchEvent(ev),繼續分發向下傳遞事件到TouchView的onTouchEvent,TouchView的onTouchEvent返回super.onTouchEvent(ev),事件沒有消費,返回給上級TouchViewGroup的onTouchEvent進行消費,TouchViewGroup的

onTouchEvent返回super.onTouchEvent(ev),繼續返回給上級TouchTraining的onTouchEvent進行消費。


方案5:

條件
控件名稱dispatchTouchEvent返回值onInterceptTouchEvent 返回值onTouchEvent 返回值
TouchTraining
super.dispatchTouchEvent(ev)----super.onTouchEvent(ev)
TouchViewGroupsuper.onInterceptTouchEvent(ev)falsesuper.onTouchEvent(ev)
TouchViewtrue----super.onTouchEvent(ev)


運行結果:

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchViewGroup: onInterceptTouchEvent攔截事件ACTION_DOWN

com.training.cj.mytraining E/TouchView: dispatchTouchEvent分發事件ACTION_DOWN

com.training.cj.mytraining E/TouchView: onTouchEvent處理事件ACTION_DOWN

com.training.cj.mytraining E/TouchTraining: dispatchTouchEvent分發事件ACTION_UP

com.training.cj.mytraining E/TouchViewGroup: dispatchTouchEvent分發事件ACTION_UP

com.training.cj.mytraining E/TouchViewGroup: onInterceptTouchEvent攔截事件ACTION_UP

com.training.cj.mytraining E/TouchView: dispatchTouchEvent分發事件ACTION_UP

com.training.cj.mytraining E/TouchView: onTouchEvent處理事件ACTION_UP


結果分析:Touch事件發生,調用TouchTraining的dispatchTouchEvent分發事件到TouchViewGroup的dispatchTouchEvent,該方法返回super.dispatchTouchEvent(ev),繼續分發事件到TouchViewGroup的onInterceptTouchEvent,該方法返回false,繼續分發事件到TouchView的dispatchTouchEvent,該方法返回super.dispatchTouchEvent(ev),繼續分發事件到onTouchEvent,由于onTouchEvent返回true,表示消費了事件,Touch事件終止。


    好了,本期的Touch事件分析到這里就結束了,另外,還有一個小細節需要注意的是,在View和View Group中的onTouchEvent方法默認返回false,View Group中的onInterceptTouchEvent也默認返回false。所以上面5種方案描述出了所有的Touch事件傳遞可能。了解Touch事件的分發和消費機制,更有利于我們自定義控件,當然我們在自定義控件時,盡量不要重寫dispatchTouchEvent這個方法。

    本貼參考博客:http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

集安市| 遂溪县| 宁波市| 宽城| 五峰| 甘谷县| 称多县| 临汾市| 德清县| 孟村| 兴业县| 通州市| 安平县| 白银市| 嘉义市| 苍梧县| 静海县| 永丰县| 前郭尔| 鄱阳县| 周至县| 嘉峪关市| 萍乡市| 高唐县| 孝感市| 竹溪县| 防城港市| 黎平县| 榕江县| 镇平县| 垦利县| 大余县| 赤峰市| 黄骅市| 白城市| 嘉义县| 三亚市| 嘉兴市| 都兰县| 林甸县| 钟山县|