1. 程式人生 > >android事件分發(三)重要的函式requestDisallowInterceptTouchEvent

android事件分發(三)重要的函式requestDisallowInterceptTouchEvent

事件分發在android中非常重要,寫了3篇文章總結其中的故事


具體實現

前面我們說過,兒子吃到肉了,父親還可能搶那麼兒子有沒有辦法不讓父親搶呢,有?

可以通過呼叫mParent.requestDisallowInterceptTouchEvent(true),之後parent就預設不攔截事件了。

這個故事就是,兒子吃到好吃的了,說,爸爸不許搶,然後爸爸就不會再搶了。

這是怎麼實現的呢?

兒子掉mParent.requestDisallowInterceptTouchEvent(true)

我們看viewgroup的requestDisallowInterceptTouchEvent方法幹了什麼?

這個函式有個bool引數,我們先看為true的情況,非常簡單,2件事情,一件是把mGroupFlags裡面的某一位置成true,然後再呼叫parent的requestDisallowInterceptTouchEvent(true)方法。總的來說就是把本viewgroup以及祖先viewgroup的那一個標誌位都置為true。

public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    if (disallowIntercept == ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0)) {
        // We're already in this state, assume our ancestors are too
        return;
    }

    if (disallowIntercept) {
        mGroupFlags |= FLAG_DISALLOW_INTERCEPT;
    } else {
        mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
    }

    // Pass it up to our parent
    if (mParent != null) {
        mParent.requestDisallowInterceptTouchEvent(disallowIntercept);
    }
}

置為true有什麼用呢?回頭看看上篇文章的ViewGroup:: dispatchTouchEvent的程式碼,有這麼一段。看下就懂了,mGroupFlags & FLAG_DISALLOW_INTERCEPT為true,那就會disallowIntercept 為true,intercepted 就為false,不會攔截,這下連起來了,mParent.requestDisallowInterceptTouchEvent(true)會導致parent下次不攔截事件。

  final boolean intercepted;  
  if (actionMasked == MotionEvent.ACTION_DOWN  
          || mFirstTouchTarget != null) {  
      final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;  
      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;  
      }  

重置時機

那麼parent是否永遠無法攔截了呢?並不是,只是在一個cycle內無法攔截,等到下一次down事件來的時候,這個標誌位會重置。程式碼在下邊,可以看到mGroupFlags的FLAG_DISALLOW_INTERCEPT標誌位會被清零。

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();
}

/**
 * Resets all touch state in preparation for a new cycle.
 */
private void resetTouchState() {
    clearTouchTargets();
    resetCancelNextUpFlag(this);
    mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
    mNestedScrollAxes = SCROLL_AXIS_NONE;
}

requestDisallowInterceptTouchEvent總結

1、          子view不希望父view攔截事件可以呼叫mParent.requestDisallowInterceptTouchEvent(true)

2、          viewgroup的mGroupFlags在下一個cycle來臨的時候,FLAG_DISALLOW_INTERCEPT標誌位會被清零

3、          requestDisallowInterceptTouchEvent這個函式一般不是自己呼叫的,而是給兒子呼叫的

4、          requestDisallowInterceptTouchEvent是解決滑動衝突的大殺器,目前大部分原生控制元件都是使用mParent.requestDisallowInterceptTouchEvent(true)來解決滑動衝突的。如何解決滑動衝突,可以看下一節

滑動衝突

相關推薦

android事件分發重要函式requestDisallowInterceptTouchEvent

事件分發在android中非常重要,寫了3篇文章總結其中的故事 具體實現 前面我們說過,兒子吃到肉了,父親還可能搶那麼兒子有沒有辦法不讓父親搶呢,有? 可以通過呼叫mParent.requestDisallowInterceptTouchEvent(true),

android事件分發

sim tdi p s oat front rac ram addclass framework 非常早之前寫過一篇android事件分發的博客,主要寫的是它是怎樣分發的,具體非常多原理的東西都沒有涉及到。今天就從源代碼看android怎樣控制它的分發機

Android事件分發3--ViewGroup原始碼分析

一、ViewGroup的onInterceptTouchEvent原始碼分析 onInterceptTouchEvent比較簡單先看他的原始碼 public boolean onInterceptTouchEvent(MotionEvent ev

Android輸入系統InputReader的加工型別和InputDispatcher的分發過程

關聯絡列 解析WMS系列 深入理解JNI系列 輸入系統系列 前言 在上一篇文章中,我們學習了輸入事件的處理,輸入事件會交由InputDispatcher進行分發,那麼InputDispatcher是如何進行分發的?這篇文章會給你答案。 1.InputReader的加工型別 在Android輸入系統(二

Android事件分發dispatchTouchEvent,攔截onInterceptTouchEvent與處理onTouchEvent

在Android中,View的結構是樹狀的,所以,當觸發觸控事件的時候,其事件傳遞也是從上之下一層層的傳遞。下面我們結合例子來一點點進行分析。 首先,我們需要了解事件處理中的幾個方法: 1、在ViewGroup中,事件分為dispatchTouchEvent(事件的分發)

Android touch 事件分發 Activity dispatchTouchEvent

/** * You can override this to intercept all touch screen events before they are dispatched to the window <br> * * @return f

android原始碼分析之View的事件分發

1、View的繼承關係圖 View的繼承關係圖如下: 其中最重要的子類為ViewGroup,View是所有UI元件的基類,而ViewGroup是容納這些元件的容器,同時它也是繼承於View類。而UI元件的繼承關係如上圖,比較常用的元件類用紅色字型標出

Android Camera2 拍照——切換攝像頭,延時拍攝和閃光模式

openca any The visible surface else 提示 再次 .cn 原文:Android Camera2 拍照(三)——切換攝像頭,延時拍攝和閃光模式

Android Studio 學習 廣播

else set local activity .... order ... void test 動態註冊監聽網絡變化 創建intentFilter 並addAction 代表了監聽哪個廣播 然後使用registerReceiver()方法 將intentFilter 與

Android 開發:安卓常用控制元件以及仿《微門戶》登入介面實現

一、常用控制元件: 1、文字類控制元件 TextView 負責展示文字,非編輯 EditText 可編輯文字控制元件 2、按鈕類控制元件 Button 按鈕 ImageButton 圖片按鈕 RadioButton與RadioGroup 單

誰擋了我的神經網路?—— 啟用函式

誰擋了我的神經網路?(三)—— 啟用函式 這一系列文章介紹了在神經網路的設計和訓練過程中,可能提升網路效果的一些小技巧。前文介紹了在訓練過程中的一系列經驗,這篇文章將重點關注其中的啟用函式部分。更新於2018.11.1。 文章目錄 誰擋了我的神經網路?(三)

Android進階:Application啟動過程(最詳細&最簡單)

1.前言 最近一直在看 《Android進階解密》 的一本書,這本書編寫邏輯、流程都非常好,而且很容易看懂,非常推薦大家去看看(沒有收廣告費,單純覺得作者寫的很好)。 上一篇簡單的介紹了Android進階(二): 應用程序啟動過程,最終知道了ActivityThrea

Android入門筆記

三、RecyclerView、ViewHolder 和 Adapter      3.1 功能概括 RecyclerView :任務僅限於回收和定位螢幕上的 View,且其自身不會建立檢視,它建立的只是 ViewHolder。 ViewHolder:容納 View

Python Numpy 100題實驗diag()函式

建立5*5的陣列,並設定1,2,3,4在對角線的下方: 使用numpy.diag()可以很方便的求出這個陣列 函式結構 diag(v, k=0) 引數說明 v 傳入一個數組,如果是一維陣列,那麼就會以這個陣列為對角線元素建立一個對角矩陣,如果傳入的陣列多於一維

Android開發筆記螢幕解析度

在app編碼中經常需要獲取手機的螢幕解析度(寬*高),原來我直接上網拷貝程式碼,但在使用過程中卻發現諸多不便。 不便一:下面程式碼中的getWidth和getHeight在adt上提示deprecated已經廢棄了,實在扎眼 WindowManager wm = get

egret 釋出android原生專案JS與原生通訊

JS與Java通訊 JS向Java傳送訊息 Java註冊接收訊息的方法: nativeAndroid.setExternalInterface("sendToNative", new INativePlayer.INativeInterface() {  &n

1 小時 SQL 極速入門——分析函式

1 小時 SQL 極速入門 前面兩篇我們從 SQL 的最基礎語法講起,到表聯結多表查詢。 大家可以點選連結檢視 1 小時 SQL 極速入門(一) 1 小時 SQL 極速入門(二) 今天我們講一些在做報表和複雜計算時非常實用的分析函式。由於各個資料庫函式的實現不太一樣,本文基於 Oracle 12c 。 R

MySQL--------常用函式

         使用函式的方便性我就不多說了,在MySQL資料庫中,函式可以使用在SELECT語句及其字句(例如WHERE、ORDER BY、HAVING等)中,也可以用在UPDATE、DELETE語句及其字句中。 一、字串函式  

Android Firebase接入--Firebase 崩潰日誌報告Crashlytics

Firebase崩潰日誌報告可以自動記錄應用內崩潰資訊,只需簡單的幾步,就可以將Firebase Crashlytics新增到安卓工程中,然後Firebase Crashlytics就會自動的收集應用內崩潰資訊,包括錯誤型別,程式碼定位等等,非常的方便實用。 一、配置A

Android-json解析:原生JSONObject+JSONArray的解析、遍歷及生成等

一、JSONObject和JSONArray的資料表示形式 JSONObject的資料是用 { } 來表示的, 例如: { "id":"1", "courseID":"化學", "title":"滴定實驗",