1.在adapter中的getView方法中儘可能少使用邏輯
2.盡最大可能避免GC
3.滑動的時候不加載圖片
4.將ListView的scrollingCache和animateCache設置爲false
5.item的佈局層級越燒越好
6.使用ViewHolderjava
不要在你的getView()中寫過多的邏輯代碼,咱們能夠將這些代碼放在別的地方,例如:android
@Override
public View getView(int position, View convertView, ViewGroup paramViewGroup) {
Object current_event = mObjects.get(position);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_event, null);
holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);
holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
//在這裏進行邏輯判斷,這是有問題的
if (doesSomeComplexChecking()) {
holder.ThreeDimention.setVisibility(View.VISIBLE);
} else {
holder.ThreeDimention.setVisibility(View.GONE);
}
// 這是設置image的參數,每次getView方法執行時都會執行這段代碼,這顯然是有問題的
RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
holder.EventPoster.setLayoutParams(imageParams);
return convertView;
}
複製代碼
@Override
public View getView(int position, View convertView, ViewGroup paramViewGroup) {
Object object = mObjects.get(position);
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.row_event, null);
holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);
holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);
//設置參數提到這裏,只有第一次的時候會執行,以後會複用
RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
holder.EventPoster.setLayoutParams(imageParams);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 咱們直接經過對象的getter方法代替剛纔那些邏輯判斷,那些邏輯判斷放到別的地方去執行了
holder.ThreeDimension.setVisibility(object.getVisibility());
return convertView;
}
複製代碼
當你建立了大量的對象的時候,GC就會頻繁的執行,因此在getView()方法中不要建立不少的對象,最好的優化是,不要在ViewHolder之外建立任何對象,若是你的你的log裏面發現「GC has freed some memory」頻繁出現的話,那你的程序確定有問題了。你能夠檢查一下:
a) item佈局的層級是否太深
b) getView()方法中是否有大量對象存在
c) ListView的佈局屬性面試
若是你的ListView中須要顯示從網絡上下載的圖片的話,咱們不要在ListView滑動的時候加載圖片,那樣會使ListView變得卡頓,因此咱們須要再監聽器裏面監聽ListView的狀態,若是滑動的時候,中止加載圖片,若是沒有滑動,則開始加載圖片網絡
listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView listView, int scrollState) {
//中止加載圖片
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
imageLoader.stopProcessingQueue();
} else {
//開始加載圖片
imageLoader.startProcessingQueue();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
}
});
複製代碼
scrollingCache: scrollingCache本質上是drawing cache,你可讓一個View將他本身的drawing保存在cache中(保存爲一個bitmap),這樣下次再顯示View的時候就不用重畫了,而是從cache中取出。默認狀況下drawing cahce是禁用的,由於它太耗內存了,可是它確實比重畫來的更加平滑。而在ListView中,scrollingCache是默認開啓的,咱們能夠手動將它關閉。ide
animateCache: ListView默認開啓了animateCache,這會消耗大量的內存,所以會頻繁調用GC,咱們能夠手動將它關閉掉佈局
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cacheColorHint="#00000000"
android:divider="@color/list_background_color"
android:dividerHeight="0dp"
android:listSelector="#00000000"
android:smoothScrollbar="true"
android:visibility="gone" />
複製代碼
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@color/list_background_color"
android:dividerHeight="0dp"
android:listSelector="#00000000"
android:scrollingCache="false"
android:animationCache="false"
android:smoothScrollbar="true"
android:visibility="gone" />
複製代碼
咱們應該儘可能減小item佈局深度,由於當滑動ListView的時候,這回直接致使測量與繪製,所以會浪費大量的時間,因此咱們應該將一些沒必要要的佈局嵌套關係去掉。減小item佈局深度性能
這個你們應該很是熟悉了,可是不要小看這個ViewHolder,它能夠大大提升咱們ListView的性能優化
ListView的優化咱們已經講完了,若是在你的項目中,這些基本優化你尚未作到的話,那麼你的ListView是有問題的,還有很大的提高潛力,之後再使用ListView的時候,必定要將這幾點考慮進去,發揮它的最大的性能。spa