<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 安卓事件傳遞機制 > 參考文章:[https://www.jianshu.com/p/238d1b753e64?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation](https://www.jianshu.com/p/238d1b753e64?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation "https://www.jianshu.com/p/238d1b753e64?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation") [](https://www.jianshu.com/p/238d1b753e64?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation)![image.png](https://upload-images.jianshu.io/upload_images/13971762-1594a6044e2eedc5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![image.png](https://upload-images.jianshu.io/upload_images/13971762-18aeeb969cd62cd0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) > DecorView屬于View體系,當它調用super.dispatchTouchEvent()方法的時候,實際上是調用ViewGroup的dispatchTouchEvent()函數。 ``` //code View.java public boolean dispatchTouchEvent(MotionEvent event) { if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onTouchEvent(event, 0); } if (onFilterTouchEventForSecurity(event)) { ListenerInfo li = mListenerInfo; if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED && li.mOnTouchListener.onTouch(this, event)) { return true; } if (onTouchEvent(event)) { return true; } } ... return false; } ``` > **在dispatchTouch()函數中,大致分成以下幾個過程:** > > 1\. 函數會優先調用onFilterTouchEventForSecurity()方法對事件進行攔截。這個函數是在特定的界面模糊不可點擊的情況下使用,一般我們不用理會。 > > 2\. View會獲取OnTouchListener回調接口,并調用回調接口來處理事件。 > > 3\. 當回調接口不予處理的時候,將調用自己的onTouch()回調來處理 > > **所以對于View類來說,它的調用過程是:** dispatchTouch( )->OnTouchListener.onTouch( )->onTouch( ) ``` //code ViewGroup.java ... if (actionMasked == MotionEvent.ACTION_DOWN) { // Throw away all previous state when starting a new touch gesture. // The framework may have dropped the up or cancel event for the previous gesture // due to an app switch, ANR, or some other state change. cancelAndClearTouchTargets(ev); resetTouchState(); } ... ``` > 在剛開始執行dispatchTouch的時候,如果當前的事件是一個down事件,ViewGroup會清掉之前所保存的按下狀態。調用的方法是cancelAndClearTouchTargets和resetTouchState。比如當前按鈕處于按下狀態,因為某種原因沒有正常反彈,通過cancelAndClearTouchTargets就可以告訴按鈕當前狀態重置了,可以回彈了。之后,會執行ViewGroup的核心方法: ``` final boolean intercepted; if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) { //判斷是否可以執行onInterceptTouchEvent final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;//判斷是否有必要執行onInterceptTouchEvent if (!disallowIntercept) { intercepted = onInterceptTouchEvent(ev); ev.setAction(action); // restore action in case it was changed } else { intercepted = false; } } else { // There are no touch targets and this action is not an initial down // so this view group continues to intercept touches. intercepted = true; } ``` > 這段代碼的核心,在于是否調用onInterceptTouchEvent回調方法。一旦onInterceptTouchEvent方法返回true,意味著這個事件需要由當前ViewGroup來處理,也就是把ViewGroup當成View來看,走上述的View事件處理流程,在此不再贅述。那么什么時候調用這個回調方法呢? **ViewGroup的事件處理過程:** > dispatchTouch() -> onInterceptTouchEvent -> (View流程) OnTouchListener.onTouch( ) -> onTouch() ### 結論: * **當ViewGroup決定攔截事件后,后續事件將默認交給它處理并且不會再調用onInterceptTouchEvent方法來判斷是否攔截。子View可以通過設置FLAG_DISALLOW_INTERCEPT標志位來不讓ViewGroup攔截除ACTION_DOWN以外的事件。** * **所以我們知道了onInterceptTouchEvent并非每次都會被調用。如果要處理所有的點擊事件那么需要選擇dispatchTouchEvent方法,而FLAG_DISALLOW_INTERCEPT標志位可以幫助我們去有效的處理滑動沖突** * Android 事件分發總是遵循 Activity => ViewGroup => View 的傳遞順序; * onTouch()?執行總優先于?onClick() > 以下圖片來源:[https://www.jianshu.com/p/38015afcdb58](https://www.jianshu.com/p/38015afcdb58 "https://www.jianshu.com/p/38015afcdb58") **Activity 的事件分發示意圖** ![image.png](https://upload-images.jianshu.io/upload_images/13971762-1fae1d7abca8cb60.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) **ViewGroup 事件分發示意圖** ![image.png](https://upload-images.jianshu.io/upload_images/13971762-8e7982bda902dc68.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) **View 的事件分發示意圖** ![image.png](https://upload-images.jianshu.io/upload_images/13971762-2c11f50b46c90b47.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) **事件分發工作流程總結** ![image.png](https://upload-images.jianshu.io/upload_images/13971762-b2ab59b9259cfa7a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看