編輯:關於Android編程
要想優化ListView首先要了解它的工作原理,列表的顯示需要三個元素:ListView、Adapter、顯示的數據;
這裡的Adapter就是用到了適配器模式,不管傳入的是什麼View在ListView中都能顯示出來。
下面簡單說下上圖的原理:1、如果你有幾千幾萬甚至更多的選項(item)時,其中只有可見的項目(滿屏顯示的Item數目)存在內存(說的優化就是說在內存中的優化!)中,其他的在Recycler中
2、ListView先請求一個type1視圖(getView)然後請求其他可見的項目。convertView在getView中是空(null)的,第一次都是為空的,只要顯示過了convertView都不為空,會保存在Recycler中
3、當item1滾出屏幕,並且一個新的項目從屏幕低端上來時,ListView再請求一個type1視圖。convertView此時不是空值了,它的值是item1。你只需設定新的數據然後返回convertView,不必重新創建一個視圖,省去了inflate和findViewById的時間,性能就得到了優化。

了解了它的工作原理後,我們就可以重復利用convertView,只要不為空就直接使用,改變它的內容就行了。
使用ListView的時候都會搭配一個Adapter,為了使得性能更優,ListView會緩存行item(某行對應的View)。ListView通過Adapter的getView函數獲得每行的item。
package com.dzt.listviewdemo;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends Activity {
private ListAdapter adapter;
private ListView lv = null;
private ArrayList list = new ArrayList();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv_list);
adapter = new ListAdapter();
for (int i = 0; i < 100; i++) {
list.add(item + i);
}
lv.setAdapter(adapter);
}
private class ListAdapter extends BaseAdapter {
private LayoutInflater mInflater;
ListAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
System.out.println(getView + position + + convertView);
viewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item, null);
holder = new viewHolder();
holder.text = (TextView) convertView.findViewById(R.id.tv_text);
holder.image = (ImageView) convertView
.findViewById(R.id.iv_img);
convertView.setTag(holder);
} else {
holder = (viewHolder) convertView.getTag();
}
holder.text.setText(list.get(position));
if (position % 2 == 0) {
holder.image.setImageResource(R.drawable.ic_launcher);
} else {
holder.image.setImageResource(R.drawable.icon);
}
return convertView;
}
}
/**
* 使用一個類來保存Item中的元素
*
* @author Administrator
*
*/
public static class viewHolder {
public TextView text;
public ImageView image;
}
}
運行效果

第一次打印的結果convertView都是為null

滑動ListView後的打印

從上面的打印消息可以看出,Recycler中會保存七個convertView對象用來顯示Item,不管你有上千個Item,也只會創建顯示滿屏的convertView,這就大大節省了內存,對viewHolder的Tag的使用也大大節省了性能開銷
Android電話撥號器實現方法
本文實例講述了Android電話撥號器實現方法。分享給大家供大家參考。具體如下:以下案例模擬android電話撥號器的實現AndroidManifest.xml清單列表&
Android SwipeRefreshLayout 官方下拉刷新控件介紹
Google提供了一個官方的下拉刷新控件SwipeRefreshLayout,個人感覺還不錯!見慣了傳統的下拉刷新,這個反而給人耳目一新的感覺(Gmail郵箱已經
[Android&Java]設計模式代碼篇:觀察者模式
觀察者,就如同一個人,對很多東西都感興趣,就好像音樂、電子產品、Game、股票等,這些東西的變化都能引起愛好者們的注意並時刻關注他們。在代碼中,我們也有這樣的一種方式來設
Android音頻開發(5):音頻數據的編解碼
前面四篇文章分別介紹了音頻開發必備的基礎知識、如何采集一幀音頻、如何播放一幀音頻、如何存儲和解析wav格式的文件,建議有興趣的小伙伴們先讀一讀,本文則重點關注如何對一幀音