有時候碰到一些比較奇葩的需求,官方提供的空間沒有辦法解決, 第三方的控件找起來也麻煩,如果是簡單的需求 最好自己熟悉自定義簡單的需求。方能不慌不亂。
自定義View,需要了解View 的生命周期,觸摸事件的傳遞,Canvas繪圖詳解。
View生命周期

觸摸事件的傳遞

觸摸事件的理解:一件觸摸事件是從手指按下屏幕到手指離開屏幕,這其中所有的觸摸都稱之為一件觸摸事件。強調(diào)下:一定要將這個過程中的所有觸摸當成一件觸摸事件看待。當一個事件不往下分發(fā)的時候 這個事件的其他任何觸摸都不會傳遞到下一級,其他事件攔截 也如此。
- 事件分發(fā) 判斷當前事件 是否往下分發(fā) 。
- 事件攔截 是否攔截當前事件。(ViewGroup)
- 事件消費 消費事件,做出業(yè)務操作。
Canvas繪圖詳解
onDraw() 具體證據(jù)業(yè)務 花自己想要的東西。
Canvas繪圖詳解
我們知道,不管是自定義View還是系統(tǒng)提供的TextView這些,它們都必須放置在LinearLayout等一些ViewGroup中,因此理論上我們可以很好的理解onMeasure(),onLayout(),onDraw()這三個函數(shù):1.View本身大小多少,這由onMeasure()決定;2.View在ViewGroup中的位置如何,這由onLayout()決定;3.繪制View,onDraw()定義了如何繪制這個View。
首先我們要理解的是widthMeasureSpec, heightMeasureSpec這兩個參數(shù)是從哪里來的?onMeasure()函數(shù)由包含這個View的具體的ViewGroup調(diào)用,因此值也是從這個ViewGroup中傳入的。這里我直接給出答案:子類View的這兩個參數(shù),由ViewGroup中的layout_width,layout_height和padding以及View自身的layout_margin共同決定。權值weight也是尤其需要考慮的因素,有它的存在情況可能會稍微復雜點。
了解了這兩個參數(shù)的來源,還要知道這兩個值的作用。我們只取heightMeasureSpec作說明。這個值由高32位和低16位組成,高32位保存的值叫specMode,可以通過如代碼中所示的MeasureSpec.getMode()獲??;低16位為specSize,同樣可以由MeasureSpec.getSize()獲取。那么specMode和specSize的作用有是什么呢?要想知道這一點,我們需要知道代碼中的最后一行,所有的View的onMeasure()的最后一行都會調(diào)用setMeasureDimension()函數(shù)的作用——這個函數(shù)調(diào)用中傳進去的值是View最終的視圖大小。也就是說onMeasure()中之前所作的所有工作都是為了最后這一句話服務的。
我們知道在ViewGroup中,給View分配的空間大小并不是確定的,有可能隨著具體的變化而變化,而這個變化的條件就是傳到specMode中決定的,specMode一共有三種可能:
MeasureSpec.EXACTLY:父視圖希望子視圖的大小應該是specSize中指定的。
MeasureSpec.AT_MOST:子視圖的大小最多是specSize中指定的值,也就是說不建議子視圖的大小超過specSize中給定的值。
MeasureSpec.UNSPECIFIED:我們可以隨意指定視圖的大小。
由TextView中源碼也可以知道這個值的設計意義是為了根據(jù)ViewGroup中具體能夠提供的空間大小來指定子View的視圖大小。
