Listview性能优化
生活随笔
收集整理的這篇文章主要介紹了
Listview性能优化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
也許你會在getView中這樣做
?
如果你在Adapter初始化的時候創建一個Listener public MyAdapter () {myListener = new View.OnClickListener() {@overridepublic void onClick(View v) {v.getTag()v.getId()//balabalabala... }}); }
?
通過傳入的View v這個參數判斷是哪一個button被點擊,這樣,無論View如何創建,你只創建了1個Listener對象這只是一個小細節,優化的方式要綜合使用,才會事半功倍
------------------7月24日更-----------------
v.getTag() 這個tag本不是用來存數據的,通俗點講它和view 的Id是同一個東西,只不過tag的類型是Object。實際上在tag中存儲數據是不符合規范的方式
但其實View類有兩種tag,
setTag(Object?tag) 方法將tag保存在一個成員變量中,findViewWithTag正是遍歷此tag
setTag(int key,?Object?tag) 方法是最終是調用View類中的setKeyedTag(int key, Object tag)
這是一個私有方法
他是用 SparseArray 實現的,我們可以把需要的東西存到這里面(其實觀察源碼可以發現,系統很多時候都是這樣做的)
這里要注意一點,參數key必須是唯一的,那么我們可以這樣做
那么需要先在res/values/strings.xml中添加
?
?
有人問,如果這樣寫,所有button只能通過id區分邏輯,無法傳入每個item的數據
我們可以將數據通過view 的tag帶進來
1 public View getView(.....) { 2 .... 3 v.setTag(key, getItem(position)); 4 .... 5 } 然后在listener中通過v.getTag()將數據取出
-----------------------7月25日update-------------------
這里我有一個失誤
如果listener里面的邏輯與當前的item有關,那么其實并不只是創建了21個listener對象
1 public void getView (View convertView ,final int position ....) { 2 if (convertView == null) { 3 View v = LayoutInflater.from(mContext).inflate(...); 4 v.setOnclickListener(new View.OnClickListener () { 5 @override 6 public void onClick(View v) { 7 getItem(position); 8 } 9 }); 10 } else { 11 12 } 13 } 你看下,如果綁定數據在convertView為空的情況下確實只創建了有限個listener,
但是在這種情況下綁定上的數據只有View創建時的7個,之后不為空的情況下沒有更換listener導致重用的view數據是新的,listener里面的position依然是過去創建view時的7個之一,不會變化(注意參數上的final)
若在else里面再重新setListener,view是有重用,listener被換成新的,并與新的position綁定,老的listener就會變成一個廢對象,等待gc回收,隨著list滾動,越來越多
關鍵是我們的業務與position這個參數有關
1.重用?convertView?
用以避免重復創建 View,重復創建 View 代價較大,而且如果重用 view 不改變寬高,重用View可以減少重新分配緩存造成的內存頻繁分配/回收;
2. 避免在 getView 中有 重復調用的 findViewById
findViewById 的實現是遍歷,如果你定義的 View 越復雜代價越大。
Google 推薦的做法是用 ViewHolder,然后保存在 view 的 tag 中。現在 RecyclerView 也是強制使用 ViewHolder 了。
3. 設置 View (如 TextView#setText )之前先對比數據是否有改變
一般來說,【比較兩個數據的代價】遠小于【 View 的重繪的代價】
4.?避免在 getView 函數中直接加載 Image 或做其他比較耗時的操作
加載本地 Image 需要載入內存以及解析 Bitmap ,都是比較耗時的操作。
用戶快速滑動列表時,會大量調用 getView ,而 getView 是在主線程中被調用的。如果你在 getView 函數中直接加載 Image 或做其他耗時操作,就會造成滑動比較卡。加載 ImageView 的解決方案就是開一個線程去把做這事。有很多第三庫可以做這事。
5. ListView 中元素避免半透明
半透明繪制需要大量乘法計算,在滑動時不停重繪會造成大量的計算,在比較差的機子上會比較卡。在設計上能不半透明就不不半透明。實在要弄的話我個人是用個比較偷懶的方法,是在滑動的時候把半透明設置成不透明,滑動完再重新設置成半透明。
6. 盡量開啟硬件加速
硬件加速提升巨大,避免使用一些不支持的函數導致含淚關閉某個地方的硬件加速。
當然這一條不只是對 ListView。
7.用 ListView 威力加強版 -- RecyclerView
更多的新武將,更多的姿勢,更規范的使用,更好用的動畫,更加強大的變化 ? 轉載自知乎(http://www.zhihu.com/question/19703384)
總結
以上是生活随笔為你收集整理的Listview性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下一个简单守护进程的实现 (D
- 下一篇: JSP proxool+mysql数据库