Android的自定義View的入門到放棄

看到這個標題是不是很難受,哈哈,個人工作的項目中關於播放器動畫的自定義View的代碼多的一大堆,彷彿寫這代碼的開發跟我從事的不是同一個工作,裏面基本上一行註釋都沒有,Duang Duang的寫了十幾個類,幾萬行代碼,心裏佩服,活了一大把年紀的,也是高人,但是寫的代碼看一眼都嫌難受。沒辦法,項目中要用到,更何況現在的我還是以UI爲主的程序員,自定義View都不懂說出去都有點丟人,還是寫點自己關於自定義View的理解

首先了解下具體的流程,就像瞭解Android組件中的Activity的生命週期一樣,少說貼圖


上圖是一個View的流程,從上至下,具體含義如下

View的onMeasure()   -->  看源碼知道這是一個final類型的方法,子類不能重寫此方法,所以一般我們加入自定義一個View繼承TextView的基類View的時候,要重寫onMeasure的方法,並設置warp_content的自身大小,不然在xml佈局文件中使用warp_content這個屬性的時候就相當於使用match_content,這個東西讓初學的我搞了半天,着重記一下。


View的onLayout()  -->  先執行layout方法,在執行onLayout的方法,layout的作用是ViewGroup用來確定子元素的位置,當ViewGroup的位置被確定後,它在onLayout中會遍歷所有的子元素並調用其layout方法。簡單的來說就是,layout方法確定View本身的位置,而onLayout方法則會確定所有子元素的位置


View的draw()   -->  這個簡單理解,就是將View繪製到屏幕上面,這個有好多方法,這個瞭解下就好,簡單形象的瞭解下就是相當於我要給我家裝修,一般步驟是 1.確定房間基調(背景),2.描繪圖案(繪製線條),3.具體圖案(繪製裝飾),以這個順序就是1.backgroud.draw, 2.onDraw,  3.onDrawForeground。就是這個順序。其中還有一個方法就是disptachDraw,這個是子類繪製的,看到這個就想到了好多其他關於disptach的方法,沒錯,這個也會有衝突,想讓自己寫的自定義View也可以優化,這點就需要考慮進去。


以上是單個View 的繪製,但是我們一般都用不到,因爲Google已經提供的一套的已經很好了,完全沒有必要需要我們重新進行寫,這是一種費力不討好的活計,我們要自己思量着來,別一下子爲自己工作的項目中引入了一大推內存問題。下來就是着重了哦,自定義ViewGroup的繪製,如圖


畫的不好,莫要吐槽

這個就是我們一個界面繪製的流程了,什麼是ViewRoot,ViewRoot對應於ViewRootImpl類,它是連接WindowManager和DecorView的紐帶,View的三大流程均是通過ViewRoot來完成的。在ActivityThread中,當Activity對象被創建完之後,會講DecorView添加到Window中,同時會創建對應的ViewRootImpl,並將ViewRootImpl和DecorView建立關聯,並保存到WindowManagerGlobal對象中。View的繪製流程是從ViewRoot的performTraversals方法開始的,它經過measure、layout和draw三個過程才能最終將一個View繪製出來


由於每種佈局的measure的方式不一樣,我這種半吊子也不好拿出來一一分析,大致上的規律也就那馬幾個,我就總結下

1. 根據各自的測量規則遍歷Children元素,調用getChildMeasureSpec方法得到Child的measureSpec
2. 調用Child的measure方法

3. 調用setMeasuredDimension確定最終的大小


onLayout的方法上述也提到,子View確定自己的位置,Group確定所有子View的位置,這邊的話方法瞭解就大差不差了,就可以控制自身的位置顯示了,反正裏面方法的參數都有註釋,直接看參數名字就可以明白,哦這個參數是要設置View的上邊距,下邊距之類的


onDraw這一塊比較重要了哦,這邊能做的操作很多,像一般動畫都放在這裏面,放點註釋在裏面就好了

  1. onDraw()函數一般由系統佈局管理器來調用,在View第一次加載的時候會調用一次,或者在系統認爲需要重繪的時候也會被調用。當然,你也可以在程序中手動觸發該View的重繪,通過調用View的invalidate()函數或者postInvalidate()函數即可,前者用於UI線程,後者用於非UI線程。
  2.  onDraw()的參數Canvas我們可以理解成系統提供給我們的一塊內存區域,所有的繪製都是在這塊內存中進行的,繪製完成後系統會顯示到屏幕中去。該Canvas對象提供了各種繪製點、線、矩形、圓、位圖的方法,基本可以滿足各種繪製要求。
  3.  drawRect函數需要提供四個座標,其中,前兩個參數代表是被繪製矩形的起始點座標,後兩個參數則是相對於起點的斜對角座標,注意,原點座標(0,0)在屏幕的左上角。
  4. onDraw()每次被調用的時候,原來畫布中的內容會被清空。






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