轉載 ANDROID LISTVIEW GETVIEW() 反覆調用

最近作項目發現一個界面當有ListView是,getView和getCount中的log被瘋狂調用。一個5個Item的ListView,getView居然會被反覆調用7組。尤爲是當ItemView中須要加載圖片時,很容易形成GC過多,很容易出現ANR。 android

緣由就在於measure過程,ListView通常都會有好多個Item,並且也會同時顯示若干組Item,這些Item的父元素都是這個ListView。 佈局

更具Google的解釋,View在Draw的時候分紅兩個階段:measure和layout,在measure階段時主要就是爲了計算兩個參數:height和width。並且要注意的是,這是個遞歸的過程,從頂向下,DecorView開始依次調用本身子元素的measure。計算完成這兩個參數後就開始layout,最後再是draw的調用。 性能

對於ListView,固然每個Item都會被調用measure方法,而在這個過程當中getView和getCount會被調用,並且看用戶的需求,可能會有不少次調用。 測試

而爲何會有不少組次調用呢? 優化

問題就在於在layout中的決定ListView或者它的父元素的height和width屬性的定義了。fill_parent會好一點,計算方法會比較簡單,只要跟父元素的大小類似就行,可是即便是fill_parent,也不能給View當飯吃,仍是要計算出來具體的dip,因此measure仍是會被調用,只是可能比wrap_content的少一點。至於自適應的它會一直考量它的寬和高,根據內容(也就是它的子Item)計算寬高。可能這個measure過程會反覆執行,若是父元素也是wrap_content,這個過程會更加漫長。 spa

因此,解決方法就是儘可能避免自適應,除非是萬不得已,固定大小或者填充的效果會比較好一些。 設計

當咱們在使用listview的時候。有時候自定義adapter的時候,是否是會發如今getview裏打印日誌的時候,重複調用不少次?有時候4次。有的嚴重甚至到10次,當咱們在listview中移動的時候。每移動一列都會調用不少次,這樣大大影響到效率!其實這和listview自己在android上的機制有關。下面我開始來介紹一下吧: 日誌

在佈局,咱們只有一個listview的時候。那好。咱們把高設置成wrap_content的時候。在listview里加載幾行看看。日誌在getview裏打印一下。是否是重複調用了?那這個辦法就好弄了。把高設置成fill_parent就成了。這個時候發現日誌仍是重複調用?那就要看一下Listview的上一級而已的高是否是也是設置也fill_parent的,若是不是。請改動吧。若是是。。。那我還真沒碰到重複調用的!由於測試好幾回了!

 若是咱們在而已裏不僅一個Listview。一個複雜好看的佈局可能有不少。listview在佈局的某個地方。這個時候有時候運氣很差。你會發現你調用了不少次getview。我測試的時候。最高230次。。。可想而知。這個速度是至關慢。並且每移動一次就是調用這麼屢次!對於這樣的狀況,在修改佈局的時候,要考慮如下兩點:1.首先考慮需求佈局和性能哪一個更重要一點。2.考慮listview周邊哪一個佈局控件影響到了它!

 若是在性能上沒有太大影響,而需求要求必需是那樣的佈局。那就以佈局爲主。看看有沒有別的方法來優化一下listview,固然前提是佈局一點都不能調整。若是能調整,佈局沒有太大變更。而listview又能很好的優化。那就固然優化了!當咱們優化的時候。首先要看一下有沒有影響到Listview重繪的控件,好比。若是它上面和下面都有控件。並且高都是wrap_content,那麼你就要設置成fill_parent或者固定高。這樣listview在高上就不會重繪,這是最主要的一點。那左右是否是也有控件(通常一個手機頁面用到list的時候不會有這麼多控件)?有,那咱們就也要調整,那就同高同樣的設置。必定要讓listview是一個固定在那個地方不動的。否則,你就等着讓他重複去調用吧!

 其實說了這麼多。最主要的仍是在咱們進行佈局的時候。要巧妙的運用每一個控件的屬性,以及瞭解控件每一個的原理。這樣在咱們進行UI設計的時候,才能很好的去結合! 遞歸

相關文章
相關標籤/搜索