(一)Canvas的save()和restore()
首先要有“分層”的一個概念爬范,比如 時鐘的 時針父腕、分針、 秒針
如果都在同一個canvas上的話青瀑,canvas旋轉(zhuǎn)后璧亮,所有的都跟著旋轉(zhuǎn)了,為了防止這種情況斥难,
canvas.save() ;
//在這中間draw枝嘶,相當于另起了一層
canvas.restore();
可以想象一下,許多層玻璃面板哑诊,在不同的玻璃面板上draw完后群扶,合在一塊,就是最后的效果
(二)canvas的坐標系
drawLine(...)也好drawPoint(...)也好镀裤,參數(shù)中傳進去的X竞阐、Y坐標點,是基于父View減去padding后的坐標系
(三)自定義View的分類
http://blog.csdn.net/jasonpeak/article/details/51729192
- 繼承 View重寫 onDraw 方法
這種方式主要用于顯示不規(guī)則的效果哦淹禾,即這種效果不方便用布局組合來實現(xiàn)馁菜,往往需要靜態(tài)或者動態(tài)的顯示一些不規(guī)則的圖形 采用這種方式需要自己支持wrap_content,并且padding也需要自己處理铃岔。
- 繼承ViewGroup派生特殊的Layout
這種方法主要用于實現(xiàn)自定義布局汪疮,即除了LinearLayout峭火,RelativeLayout等系統(tǒng)布局之外的一種重新定義的全新的布局,當某種效果很像 幾種View組合在一起的時候就可以采用這種方法智嚷。 這種方法稍微復雜一些卖丸,需要合適的處理ViewGroup的測量和布局這倆個過程 - 繼承特定的View(比如TextView)
這種方法一般用于擴展某種已有的View功能。這種方法不需要自己支持wrap_content盏道,padding等稍浆。 - 繼承特定的ViewGroup(比如LinearLayout等)
當某種效果很像幾種View組合在一起的時候就可以采用這種方法。這種方法不需要自己處理ViewGroup的測量和布局這倆個過程猜嘱。 與1.2比較衅枫,一般來說,1.2能實現(xiàn)的效果1.4也都能實現(xiàn)朗伶,但1.2更接近View的底層弦撩。
自定義View的注意事項
- 讓View支持wrap_content
這是因為直接繼承View或ViewGroup的控件,如果不在onMeasure中處理wrap_content,那么外界在布局中使用wrap_content時就無法達到預期效果 - 讓View支持padding
直接繼承View的控件论皆,如果不再draw方法中處理padding益楼,那么這個屬性是無法起作用的。 直接繼承ViewGroup的控件需要在onMeasure和onLayout中考慮padding和子元素的margin對其造成的影響点晴,不然將導致pading和子元素的margin失效 - 不要在View中使用Handler
這是因為View內(nèi)部本身就提供了post系列方法感凤,完全可以替代Handler的作用。除非你很明確要用Handler來發(fā)送消息粒督。 - View中如果有線程和動畫陪竿,及時停止
如果有線程和動畫需要停止的時候,onDetachedFromWindow就惡意做到坠陈。這是因為當包含此View的Activity退出或者當前View被remove時萨惑,View的onDetachedFromWindow方法就會被調(diào)用。相對的仇矾,當包含此View的Activity啟動時onAttachedToWindow會被調(diào)用庸蔼。同時,View不可見時贮匕,我們也需要停止線程和動畫姐仅,如果不及時停止,可能會導致內(nèi)存泄漏刻盐。 - 如果有滑動嵌套時掏膏,當然要處理好滑動沖突的問題。