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":"滴定實驗",