亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

如何實現Android觸摸事件分發的原理分析

發布時間:2022-01-10 00:25:20 來源:億速云 閱讀:116 作者:柒染 欄目:開發技術

如何實現Android觸摸事件分發的原理分析,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。


    一:前言

    最近在學Android的觸摸事件分發,我覺得網上說的太雜太亂,而且有很多博客都有明顯的錯誤。什么自頂向下分發,自下向頂分發,什么攔截又一直消費什么什么之類,非常難懂。為了自己將來回顧可以更好的理解這塊知識,也為了后來之人可以更好的學習,我寫下這篇博客。

    二:說在前面的知識

    • 點擊,滑動,松手都是由MotionEvent這個類來表示。

    • 屏幕上的一個事件序列是指以一個MotionEvent.action_down按下開始,以若干個MotionEvent.action_move移動事件在中間,再以一個MotionEvent.action_up作為結束的事件流。

    • view group是view的子類。view group和view都有dispatchTouchEvent方法;view group有onTnterceptTouchEvent和onTouchEvent方法,view 只有onTouchEvent方法。

    三:整體流程

    1:activity

    我們點擊屏幕的所有事件,都會被第一個接收。

    public boolean dispatchTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                onUserInteraction();//是一個空方法,如果想知道按下了屏幕,可以重寫這個方法打印日志
            }
            if (getWindow().superDispatchTouchEvent(ev)) {//把這個事件傳給window屬性
                return true;
            }
            return onTouchEvent(ev);
        }

    2:window就是PhoneWindow

    每一個activity都會對應一個PhoneWindow(在onCreate方法之前、activity內部的attach方法中創建)。PhoneWindow含有一個decor view屬性(setContentView中創建),phone window把事件傳給decor view。 decor view繼承于view group。點擊事件現在傳到decor view這里,就開始view group的事件分發邏輯了。

    3:view group

    view group收到點擊事件, 進入dispatchTouchEvent, 如果滿足以下二個條件中的任何一個條件:

    • 事件為down事件

    • 有一個子view或子view group在處理著事件流了

    mFirstTouchTarget !=null

    就進入判斷,如果沒有被禁用攔截(子view調用parent.requestDisallowed....)就執行, onInterceptTouchEvent代碼。

    如果決定攔截,后面還會把mFirstTouchTarget置為null,這樣,之后就不會在調用onInterceptTouchEvent了。而且之后的事件流都會由這個view group的dispatchTouchEvent處理

    如果不決定攔截,就遍歷子view、子view group,挨個調用它們的dispatchTouchEvent如果沒有人接收,那就調用自己的super.dispatchTouchEventview group的super.dispatchTouchEvent就是自己view那部分 的 dispatchTouchEvent

    4:view

    在view這一層,對于down事件,返回true就表示消費這個down事件之后的序列。具體看圖。

    如何實現Android觸摸事件分發的原理分析

     view調用setOnTouchLIstener可以設置OnTouchListener,重寫onTouch方法。從源碼中可以看出,若onTouch返回true,將不再回調onTouchEvent方法。不回調onTouchEvent的話,那onClickListener也不能回調了。

    四:一些關鍵點

    即使有view消費著一組事件,事件流由底向上傳遞時,依然會調用每一個view group的intercept攔截方法判斷是否攔截。當一個view group遍歷它所有的子view沒有一個接收時,就會進入view模式,調用自己繼承于view的那一個dispatchTouchEvent方法。如果自己不接收,那會交給調用自己的dispatchTouchEvent的那個父view.

    事件流沒有什么自上而下,就是自下而上的。

    ViewGroup的實現負責將觸摸事件沿著控件樹向子控件進行派發,而View的實現則主要用于事件接收與處理工作。當view group沒有子view接收時,view group作為一個“view”去處理。

    五:從源碼看觸摸事件分發

    由于專欄關注自定義控件,所以關于系統如何從硬件獲取觸摸事件以及傳遞到Activity的dispatchTouchEvent就不詳細分解,下面將從Activity的dispatchTouchEvent方法來一步步看事件是如何被分發傳遞的:

    Activity中的dispatchTouchEvent:

        public boolean dispatchTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
                onUserInteraction();
            }
            if (getWindow().superDispatchTouchEvent(ev)) {
                return true;
            }
            return onTouchEvent(ev);
        }

    其中onUserInteraction();是一個空實現,是系統留給我們的一個修改事件分發的一個方法,這里可以忽略。

    所以實際上Activity的dispatchTouchEvent方法是調用的PhoneWindow的superDispatchTouchEvent方法,如果superDispatchTouchEvent返回false,沒有消費掉事件,那么才會再交給activity的onTouchEvent方法去處理,從這個角度來講,如果所有地方都沒有消費掉事件,最后接收事件的會是Activity的onTouchEvent方法。

    那么下面我們來看看PhoneWindow中的superDispatchTouchEvent方法:

        @Override
        public boolean superDispatchTouchEvent(MotionEvent event) {
            return mDecor.superDispatchTouchEvent(event);
        }

    發現實際上調用的是DecorView對象mDecor的superDispatchTouchEvent方法,來看看DecorView的superDispatchTouchEvent方法:

            public boolean superDispatchTouchEvent(MotionEvent event) {
                return super.dispatchTouchEvent(event);
            }

    調用的super.dispatchTouchEvent,而再來看看這個DecorView的繼承關系:

    private final class DecorView extends FrameLayout implements RootViewSurfaceTaker

    所以調用的是FrameLayout中的dispatchTouchEvent方法,而FrameLayout并沒有重寫dispatchTouchEvent方法,所以實際調用的是FrameLayout的父類 ---> ViewGroup中的dispatchTouchEvent方法,下面這個圖描述了從系統得到MotionEvent實際到傳遞給DecorView的super.dispatchTouchEvent的過程:

    如何實現Android觸摸事件分發的原理分析

    看完上述內容,你們掌握如何實現Android觸摸事件分發的原理分析的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

    向AI問一下細節

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

    AI

    容城县| 平谷区| 保定市| 虎林市| 鹿邑县| 漳浦县| 宁武县| 曲水县| 如皋市| 白水县| 龙南县| 阿合奇县| 贺兰县| 平和县| 修武县| 西乡县| 大港区| 土默特右旗| 兰考县| 孝昌县| 石阡县| 西昌市| 常德市| 宁阳县| 兴和县| 大城县| 崇左市| 海宁市| 武强县| 琼海市| 左云县| 龙陵县| 同江市| 秀山| 漳平市| 九龙城区| 屯门区| 木兰县| 比如县| 高台县| 临安市|