參考:http://blog.csdn.net/yanbober/article/details/45887547
工程git地址
http://git.oschina.net/blnm/anzhuoviewchumochuandi
花了3天研究了上面的博客 主要是View篇, 總結(jié)出一些比較簡(jiǎn)單易懂 結(jié)論.我猜很多人像我一樣也是不愿意看源碼的,只是想知道怎么用而已,使用對(duì)象,而不需要了解對(duì)象實(shí)現(xiàn)功能的原理.
網(wǎng)上有些博客說(shuō)的是錯(cuò)的,本文經(jīng)過(guò)我代碼測(cè)試,基本毛病不大.
View 觸摸相關(guān)的方法有很多比如下面的
可以寫(xiě)在activity里的方法:
setOnClickListener
setOnTouchListener
寫(xiě)在自定義view里的方法
dispatchTouchEvent (返回值表示接收到手勢(shì)事件) A
onTouchEvent (返回值表示接收到手勢(shì)事件) ?B
B影響A
event是觸摸對(duì)象 ?event里面有個(gè)action屬性 ?
Action 有3個(gè)狀態(tài) 和對(duì)應(yīng)的int值 :?
down--0
?move--2
?up--1
基本順序:
dispatchTouchEvent ->onTouchListener ->onTouchEvent(前3個(gè)是循環(huán) 因?yàn)閍ction 有3種狀態(tài) 所以會(huì)循環(huán)3次 第三次up執(zhí)行下面的) ->setOnClickListener
在View的觸摸屏傳遞機(jī)制中通過(guò)分析dispatchTouchEvent方法源碼我們會(huì)得出如下基本結(jié)論:
觸摸控件(View)首先執(zhí)行dispatchTouchEvent方法墩新。
dispatchTouchEvent返回值與View里的該方法做了什么
先調(diào)用View里的方法,第一次接收到action (一般是down狀態(tài)), 執(zhí)行__________A邏輯__________,如果設(shè)置了ontouchListern 或者 onTouchEvent都會(huì)返回true
返回true 就會(huì)繼續(xù)接受touch的 后續(xù)動(dòng)作 如:move? UP? 如果返回false? 接收不到后面的 動(dòng)作 (或者說(shuō)是狀態(tài))了
下面是A,B 2個(gè)邏輯是根據(jù)源碼得出的結(jié)論
__________A邏輯____start______:如果設(shè)置了onTouchListener事件
返回值為true ?那么 dispatchTouchEvent ?返回 ture onTouchEvent不執(zhí)行
如果沒(méi)有設(shè)置onTouchListener事件 或者設(shè)置返回值為false? 則會(huì)調(diào)用onTouchEvent(event)
onTouchEvent 返回值參照___邏輯B____.
onTouchEvent的返回值會(huì)影響下次dispath的返回值 (如果true 該View接收事件 如果是false就是接收不到action下面的狀態(tài))
onClickListerner就在onTouchEvent中被調(diào) 執(zhí)行的,而且是在onTouchEvent的ACTION_UP事件中執(zhí)行的窟坐。
/____A邏輯____end___
__________B邏輯______start____
onTouchEcent默認(rèn)是返回false
如設(shè)置view.setClickable 或者設(shè)置onClickListerner:達(dá)到onTouchEcent返回true
v.setEnabled(false);(enable如果false ?onTouchListerner 和onClickListerner2個(gè)方法不執(zhí)行)
v.setClickable(true);
onTouchEvent直接消費(fèi)事件返回true
v.setEnabled(false);
v.setClickable(false);
onTouchEvent返回false
v.setEnabled(true);
v.setClickable(false);
onTouchEvent返回false
v.setEnabled(true);
v.setClickable(true);
onTouchEvent返回true
---------------------------------
View如果沒(méi)寫(xiě)回調(diào)事件 默認(rèn)onTouchEvent返回false
如果只寫(xiě)了onClickonTouchEvent返回true
如果寫(xiě)了onTouchListerner? (這個(gè)方法返回false onTouchEvent返回true 這個(gè)方法返回true? onTouchEvent不執(zhí)行)
自動(dòng)以按鈕 繼承系統(tǒng)按鈕 執(zhí)行順序如下
dispatchTouchEvent方法先派發(fā)down事件海渊,完事調(diào)運(yùn)onTouch绵疲,完事調(diào)運(yùn)onTouchEvent返回true,同時(shí)dispatchTouchEvent返回true切省,然后dispatchTouchEvent繼續(xù)派發(fā)move或者up事件最岗,循環(huán)帕胆,直到onTouchEvent處理up事件時(shí)調(diào)運(yùn)onClick事件朝捆,完事返回true,同時(shí)dispatchTouchEvent返回true懒豹;一次完整的View事件派發(fā)流程結(jié)束
/_________B邏輯___end_______
下面是ViewGroup具體總結(jié)如下:
Android事件派發(fā)是先傳遞到最頂級(jí)的ViewGroup芙盘,再由ViewGroup遞歸傳遞到View的。
在ViewGroup中可以通過(guò)onInterceptTouchEvent方法對(duì)事件傳遞進(jìn)行攔截脸秽,onInterceptTouchEvent方法返回true代表不允許事件繼續(xù)向子View傳遞儒老,返回false代表不對(duì)事件進(jìn)行攔截,默認(rèn)返回false记餐。
子View中如果將傳遞的事件消費(fèi)掉驮樊,ViewGroup中將無(wú)法接收到任何事件。
在Activity的觸摸屏事件派發(fā)中:
首先會(huì)觸發(fā)Activity的dispatchTouchEvent方法片酝。
dispatchTouchEvent方法中如果是ACTION_DOWN的情況下會(huì)接著觸發(fā)onUserInteraction方法囚衔。
接著在dispatchTouchEvent方法中會(huì)通過(guò)Activity的root View(id為content的FrameLayout),實(shí)質(zhì)是ViewGroup雕沿,通過(guò)super.dispatchTouchEvent把touchevent派發(fā)給各個(gè)activity的子view练湿,也就是我們?cè)貯ctivity.onCreat方法中setContentView時(shí)設(shè)置的view。
若Activity下面的子view攔截了touchevent事件(返回true)則Activity.onTouchEvent方法就不會(huì)執(zhí)行审轮。