安卓整體梳理二(View的事件體系)

安卓中的View是所有控件的基類,ViewGroup也是繼承於View

一、View的位置參數:

1、top,left,right,bottom,是View左上角和右下角的座標,是相對於父容器的相對座標,可以通過View.getLeft()...得到。

      這幾個座標是表示View的原始位置,不會因爲發生偏移而變化

2、x,y,是View左上角的座標 ,是View左上角的座標,也是相對於父容器的相對座標,可以通過View.getX()...得到。

     這個座標是表示View的當前位置,會因爲發生偏移而變化

3,如果View在原來的位置上發生了偏移,那麼可以用tanslationX,translationY來描述偏移量

     x=left+translationX ,  y=top+tanslationY;

二、MotionEvent

當觸摸屏幕產生點擊事件之後,會產生幾種典型的事件:ACTION_DOWN,ACTION_MOVE,ACTION_UP,我們可以通過MotionEvent獲取到點擊事件的座標,其中getX,getY返回的是相對於當前View左上角的座標,getRowX,getRowY返回的是相對於手機屏幕左上角的x和y座標,一般在自定義View的onTouchEvent裏獲取MotionEvent。

三、VelocityTraker,GestureDetector,和Scroll

1、VelocityTraker用於速度追蹤,計算當前的滑動速度,只需將MotionEvent傳入,然後設置統計的時長(ms),就能算出設定時長裏的滑動距離從而計算速度。

2、GestureDetector用戶輔助檢測用戶手勢(單擊,滑動,長按,雙擊等),傳入MotionEvent作爲參數,就可以輔助檢測手勢, 當然也可以在onTouchEvent裏自己判斷MotionEvent。

四、View的滑動

  1. 使用scrollTo/scrollBy,這種方式只能改變View的內容的位置,不能改變View的位置,通過這種方式滑動時,view的mScrollX和mScrollY的值發生變化
  2. 使用動畫,分爲View動畫(android.view.animation包)和屬性動畫(android.animation包),其中View動畫只能操作View的影像,並不能真正改變View的位置參數,屬性動畫則沒有這個問題,優點是能實現複雜的效果   (注意:這裏的改變位置參數指的是改變View的xy座標,View的Top,Left等參數保持不變)
  3. 改變佈局參數,通過改變LayoutParams,操作稍複雜

四、View的事件分發

      也就是對MotionEvent的分發,當一個MotionEvent產生以後,系統需要把這個事件傳遞給一個具體的View,這個傳遞過程就是分發過程,主要是三個重要方法:dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent,(同一事件序列,指的是從Down,到move ,最後up的一系列動作)

      1. public bool dispatchTouchEvent(MotionEvent ev),

         用來分發事件,如果事件傳遞給當前View,那麼這個方法一定會被調用,返回值表示是否消耗當前事件

      2. public bool onInterceptTouchEvent(MotionEvent ev),

         用來判斷是否攔截某個事件,如果當前View攔截了某個事件,那麼在同一事件序列中,這個方法不會再次被調用。 

         一般來說一個事件只能被一個View攔截且消耗。 

         一旦某個View決定攔截一個事件,那麼同一個序列後續事件都會由他處理。 

         ViewGroup默認不攔截任何事件(本方法默認返回false)

      3. public bool onTouchEvent(MotionEvent ev),

         用來表示是否要消耗當前事件,如果不消耗,那麼同一時間序列中,當前View不會再次接收到事件。

         如果View一旦開始處理事件,如果沒有消耗ACTION_DOWN事件(返回false),那麼同一序列的其他事件就不會再交給他處理,而是由父View的onTouchEvent來處理

 

  總的判斷流程就是:當根ViewGroup接收到一個點擊事件之後,他的 dispatchTouchEvent就會被調用來進行分發的判斷,如果他的onInterceptTouchEvent返回ture,就表示這個group要攔截這個事件,然後就會調用他的onTouchEvent去處理這個事件,而如果onInterceptTouchEvent返回的是false,那麼表示他不處理這個事件,事件就會被分發到子View,接着子View的dispatchTouchEvent就會被調用。 事件分發是由 Acitvity--Window--頂級View--下級View,這裏考慮一個情況,如果View從上到下,onInterceptTouchEvent都返回false,就是都不攔截事件而是交給下一級來處理,那麼到最下一ViewGroup的onInterceptTouchEvent返會true,攔截了事件(或者是View,View沒有onInterceptTouchEvent,事件傳遞進來就會調用OnTouchEvent),但是onTouchEvent返回了false,沒有消耗事件,那麼事件將由他的上級View的onTouchEvent來處理,如果都返回false,那麼就會層層上傳,最後由Activity的onTouchEvent來處理。

 

滑動衝突解決方案*(待完善)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章