Android性能優化之Listview(ViewHolder重用機制)

好久沒發博客了,因爲發博客太耗時間了,而且參考的比較多,也不想一直帶着轉載兩個字。都一直放在筆記裏。不過只能自己看不能和大家分享了,看到這篇文章令我恍然大悟,很有幫助,所以還是決定寫下來。

相信大家在很多時候都會用到ListView這個控件,因爲確實是用的很多很多,但是有木有遇到過當數據很多很多的時候,往下滑ListView時有時候會卡頓,這就需要我們來優化它了。

 

ListView優化主要有下面幾個方面:

1、convertView重用

2、ViewHolder的子View複用

3、緩存數據複用

 

一、convertView重用

首先講下ListView的原理:ListView中的每一個Item顯示都需要Adapter調用一次getView()的方法,這個方法會傳入一個convertView的參數,這個方法返回的View就是這個Item顯示的View。如果當Item的數量足夠大,再爲每一個Item都創建一個View對象,必將佔用很多內存空間,即創建View對象(mInflater.inflate(R.layout.lv_item, null);從xml中生成View,這是屬於IO操作)是耗時操作,所以必將影響性能。Android提供了一個叫做Recycler(反覆循環)的構件,就是當ListView的Item從滾出屏幕視角之外,對應Item的View會被緩存到Recycler中,相應的會從生成一個Item,而此時調用的getView中的convertView參數就是滾出屏幕的緩存Item的View,所以說如果能重用這個convertView,就會大大改善性能。

那麼,我們怎麼重用它呢?貼代碼:

如圖,當這個convertView不存在時,即第一次使用它,我們就創建一個item佈局的View對象並賦給convertView,以後使用convertView時,只需從convertView中getTag取出來就可以,不需要再次創建item的佈局對象了,這樣便提高了性能。

二、使用ViewHolder重用

我們都知道在getView()方法中的操作是這樣的:先從xml中創建view對象(inflate操作,我們採用了重用convertView方法優化),然後在這個view去findViewById,找到每一個item的子View的控件對象,如:ImageView、TextView等。這裏的findViewById操作是一個樹查找過程,也是一個耗時的操作,所以這裏也需要優化,就是使用ViewHolder,把每一個item的子View控件對象都放在Holder中,當第一次創建convertView對象時,便把這些item的子View控件對象findViewById實例化出來並保存到ViewHolder對象中。然後用convertView的setTag將viewHolder對象設置到Tag中, 當以後加載ListView的item時便可以直接從Tag中取出複用ViewHolder對象中的,不需要再findViewById找item的子控件對象了。這樣便大大提高了性能。

貼個完整的代碼:


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