ListView卡頓問題解決

產生卡頓的原因:

1..Adapter的getView方法裏面convertView沒有使用setTag和getTag方式;
2.在getView方法裏面ViewHolder初始化後的賦值或者是多個控件的顯示狀態和背景的顯示沒有優化好,抑或是裏面含有複雜的計算和耗時操作;
3.在getView方法裏面 inflate的row 嵌套太深(佈局過於複雜)或者是佈局裏面有大圖片或者背景所致;
4.Adapter多餘或者不合理的notifySetDataChanged;
5.listview 被多層嵌套,多次的onMessure導致卡頓,如果多層嵌套無法避免,建議把listview的高和寬設置爲fill_parent. 如果是代碼繼承的listview,那麼也請你別忘記爲你的繼承類添加上LayoutPrams,注意高和寬都是fill_parent的;
解決辦法:

1. 就用就行了

2.也好解釋,儘量不要太耗時

3.如果有從服務器加載大圖,用到了volley的ImageRequest的話,那麼可以用if(holder.imageRequest != null) holder.imageRequest.cancle(); 然後重新賦值request加到queue中去(這個沒有實踐過,只是這麼想)

4.一般人不會這麼做吧。。。

5.原因說一下(別人分析的)

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,這個過程會更加漫長。

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

於是我們把listview與他父控件的所有高度與寬度都設置爲fill_parent,果然getview調用正常了,注意是所有的高度和寬度!



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