編輯:關於Android編程
android系統中的每個ViewGroup的子類都具有下面三個和TouchEvent處理密切相關的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev) 這個方法用來分發TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 這個方法用來攔截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 這個方法用來處理TouchEvent
注意:不是所有的View的子類,很多教程都說的是所有的View的子類,只有可以向裡面添加View的控件才需要分發,比如TextView它本身就是最小的view了,所以不用再向它的子視圖分發了,它也沒有子視圖了,所以它沒有dispatch和Intercept,只有touchEvent。
說明: 白色為最外層,它占滿整個屏幕;
紅色為中間區域,屬於白色中的一層;
黑色為中心區域,必於紅色中的一層。
注意:他們本質上是:LinearLayout,而不是RelativeLayout或者其它布局。
1.由中心區域處理touch事件
布局文件如下:
復制代碼
注意: android:clickable="true"
接下來我們看一下打印的日志:
結合是上面的日志,我們可以看一下ACTION_DOWN事件處理流程:
說明:
首先觸摸事件發生時(ACTION_DOWN),由系統調用Activity的dispatchTouchEvent方法,分發該事件。根據觸摸事件的坐標,將此事件傳遞給out的dispatchTouchEvent處理,out則調用onInterceptTouchEvent 判斷事件是由自己處理,還是繼續分發給子View。此處由於out不處理Touch事件,故根據事件發生坐標,將事件傳遞給out的直接子View(即middle)。
Middle及Center中事件處理過程同上。但是由於Center組件是clickable 表示其能處理Touch事件,故center中的onInterceptTouchEvent方法將事件傳遞給center自己的onTouchEvent方法處理。至此,此Touch事件已被處理,不繼續進行傳遞。
2.沒有指定誰會處理touch事件
布局文件如下:
復制代碼
注意:只是比上一次的布局少了android:clickable="true"
接下來我們看一下打印的日志
結合是上面的日志,我們可以看一下ACTION_DOWN事件處理流程:
說明:
事件處理流程大致同上,區別是此狀態下,所有組件都不會處理事件,事件並不會被center的onTouchEvent方法“消費”,則事件會層層逆向傳遞回到Activity,若Activity也不對此事件進行處理,此事件相當於消失了(無效果)。
對於後續的move、up事件,由於第一個down事件已經確定由Activity處理事件,故up事件由Activity的dispatchTouchEvent直接分發給自己的onTouchEvent方法處理。
代碼請看最後的附件
總結:
1) Touchevent 中,返回值是 true ,則說明消耗掉了這個事件,返回值是 false ,則沒有消耗掉,會繼續傳遞下去,這個是最基本的。
2) 事件傳遞的兩種方式:
隧道方式:從根元素依次往下傳遞直到最內層子元素或在中間某一元素中由於某一條件停止傳遞。
冒泡方式:從最內層子元素依次往外傳遞直到根元素或在中間某一元素中由於某一條件停止傳遞。 android對Touch Event的分發邏輯是View從上層分發到下層(dispatchTouchEvent函數)類似於隧道方式,然後下層優先開始處理Event(先mOnTouchListener,再onTouchEvent)並向上返回處理情況(boolean值),若返回true,則上層不再處理。類似於冒泡方式
於是難題出現了,你若把Touch Event都想辦法給傳到上層了(只能通過返回false來傳到上層),那麼下層的各種子View就不能處理後續事件了。而有的時候我們需要在下層和上層都處理Touch事件
舉個例子,ViewFlipper用來檢測手勢,在內部我們放幾個Image,有點像gallery的效果,也就是左右滑動切換圖片,但是圖片有時候我們希望可以放大縮小!這樣就會存在ViewFlipper裡面需要touch事件,而在image裡面也需要一個touch事件(當圖片大小屏幕邊界的時候可以拖動圖片,而不是左右切換圖片)。
前言1、什麼是NDK?NDK全稱是Native Development Kit,NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,並能自動將so和jav
MediaPlayer通過如下兩個靜態方法來加載指定的音頻: 1、static MediaPlayer create(Context context,Uri uri
最近的項目中給ListView 加入了一個Header View之後,發現Header View的下方也有了分割線,很難看,UI要求將Header View的分割器去掉
先來看看效果圖就是簡單的根據手指寫下的軌跡去畫出內容一、實現之前一篇文章裡提到了android官方給出的自定義控件需要考慮以下幾點:創建View處理View的布局繪制Vi