91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

隨我一起慢慢揭開Andoird里事件分發機制的神秘面紗

發布時間:2020-04-02 22:29:52 來源:網絡 閱讀:395 作者:屠夫章哥 欄目:移動開發

轉載好文章:

    http://blog.csdn.net/chunqiuwei/article/details/41084921

    


 學了這么久的Android,面試也常被問到事件分發機制,但總感覺對這個機制還是不清不楚.突然之間

 翻了一下李剛的<Crazy Android>,突然有了一些感悟,所以就立馬記下來:


一、監聽與回調

   第一,要明白和事件相關的3個概念:事件源,事件,事件監聽器.

   事件源:就是事件作用的對象

   事件:就是事件本身,可以是點擊,長按,移動等等,就是XxxEvent.

   事件監聽器:就是Listener,一般寫成內部類的形式,說白了,就是一個類,而這個類往往是事件源

           內部的接口實現類。 


   第二,<Crazy Android>上總結得很到位:Android中的事件處理機制可以分為兩大類,監聽回調.

   監聽:就是給控件添加一個監聽器,即addXxxListener(new XxxListener(){...}),事件源本身不直

      接處理,而是交由事件監聽器進行處理.

   回調:當事件作用在事件源的時候,事件源本身會觸發一些自己的方法,自己來處理事件.但往往事件

     源的這些方法是封裝在事件源對象的內部的,用戶看不見.這也就是為什么需要有監聽器的原

     因,讓用戶知道事件源發生了什么事件.通常在自定義控件的時候,就需要復寫和Touch相關的

     事件,同時抽取監聽器接口,讓用戶去實現.


-----------------------------------------------------------------------------------------

   舉個小例子:

      假如有這樣一個需求:點擊一下Button,打印一條日志.

      那么有2種實現方式

      第1種實現方式-為Button設置監聽器

         Button.setOnClickListener(new OnClickListener(){

         onClick(View view)

           {

              Log...

            } 

         }); 

      第2種實現方式-繼承Button,自定義一個MyButton

         定義的時候,復寫Button的onTouchEvent方法,在里面打印日志.

      

     那么,現在又有一個需求:點擊一下Button,彈出一個吐司.

      如果采用第1種方式,只要修改一下onClick里的代碼.

      如果采用第2種方式,那么1種辦法是再創建一個Button的子類,另外一個方法就是修改原來

        MyButton的onTouchEvent方法,但是這樣一來又不能滿足開始的需求了.

      

      所以到這里,監聽與回調的區別也就不言而喻了吧.

       1)監聽只是組件的作者在寫回調方法時,暴露給用戶的一個接口,這樣用戶可以實現接口,

        達到自身的需求,最終用戶實現的接口里的方法在組件的回調方法里會被回調。

       

二、結合2.3.3中View的源碼,再談監聽與回調 

   1.View的dispatchTouchEvent方法

    我之前一直沒有搞清楚View的dispatchTouchEvent的返回值的作用,現在明白了,

    返回true,作用在View上的觸摸事件(包括Button的點擊事件)就會生效;

    返回false,作用在View上的觸摸事件就失效。

    但具體dispatchTouchEvent方法又在哪里被調用了呢(?????????????) 

     public boolean dispatchTouchEvent(MotionEvent event) {
           。。。
            if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
                    mOnTouchListener.onTouch(this, event)) {
                return true;
            }
            return onTouchEvent(event);
     }

   

       2)監聽是先判斷的,所以監聽比回調的優先級要高。先判斷listener.onTouch的返回值

        ,否則就return onTouchEvent(event)將事件交由組件的onTouchEvent回調方法進行處理。

     

     所謂View的事件分發,解決的問題就是事件是由用戶處理還是View自身處理

       

三、結合2.3.3中ViewGroup的源碼,再談監聽與回調       

     

    由于ViewGroup的dispatch事件源碼過多,我就不一一寫了,大致地去描述一下。

     ViewGroup的dispatch事件干的事:


     先弄一個變量來緩存可能會捕捉并處理事件的View,target.

     在點擊ev.getAction == MotionEvent.Action_Down的事件里

       根據onIntercept事件判斷自己需不需要攔截事件,如果不攔截,則遍歷ViewGroup里的

     每個子View,通過計算子View的矩形區域來判斷點擊事件的坐標有沒有落在子View上,如果點

     擊事件的坐標落在子View并且子View捕捉并處理事件,那么target就等于這個子View。


        判斷target是否為null

            如果為null,則調用ViewGroup的父類的dispatch事件,也就是把ViewGroup當作

         View來處理。

            如果不為null,則交由target.dispatch事件進行處理。


    所謂ViewGroup的事件分發,解決的問題就是事件到底是由哪個View來處理。



四、FrameLayout的事件分發機制

    我們都知道,ViewGroup的事件傳遞順序是由父控件往子控件傳遞,但是假如是FrameLayout的兩

    個子控件重疊在一起,并且兩個子控件沒有包含(父子)關系,那么事件的傳遞順序是怎樣的呢

   

    其實這個Android源碼里已經說得十分地清楚了,

// Scan children from front to back.

    也就是從上往下查找,自然事件也是從上往下傳遞。


    1)在做《風口》項目時,我也遇到過這種問題:

        明明點擊的地方什么也沒有,但是事件卻被響應了。我將布局看來看去,想了很久,突然

    明白這就是事件分發導致的。FrameLayout的上層Layout點擊的位置沒有控件響應事件,但是在下

    一層的Layout中,鼠標點位的位置有控件響應。這種解釋了這種見鬼的原因!

    2)小資錢包首頁,“馬上搶購”按鈕和它所在的父布局響應同樣的事件。

     第1種方法:給2者注冊同一個監聽器 

     第2種方法:屏蔽Button對事件的響應,只注冊父布局的監聽。(即怎么讓按鈕可點擊但是不響

          應點擊事件)

          復寫Button onIntercept方法返回false.

    

      

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

诸暨市| 泸西县| 镇安县| 开江县| 福清市| 宜章县| 乌苏市| 玉田县| 济宁市| 罗平县| 苍溪县| 蓝田县| 台中市| 巴林右旗| 镇远县| 双江| 浑源县| 湟中县| 大安市| 肥西县| 贵德县| 昂仁县| 合江县| 泗阳县| 周至县| 乌拉特后旗| 永定县| 疏勒县| 阜阳市| 峨眉山市| 霍林郭勒市| 改则县| 东港市| 桑植县| 锦屏县| 石嘴山市| 新河县| 襄城县| 霞浦县| 太湖县| 秦皇岛市|