本帖最后由 51黑bing 于 2016-3-22 19:41 編輯
要想優(yōu)化ListView首先要了解它的工作原理,列表的顯示需要三個元素:ListView、Adapter、顯示的數(shù)據(jù);
這里的Adapter就是用到了適配器模式,不管傳入的是什么View在ListView中都能顯示出來。 下面簡單說下上圖的原理:
1、如果你有幾千幾萬甚至更多的選項(item)時,其中只有可見的項目(滿屏顯示的Item數(shù)目)存在內(nèi)存(說的優(yōu)化就是說在內(nèi)存中的優(yōu)化!)中,其他的在Recycler中 2、ListView先請求一個type1視圖(getView)然后請求其他可見的項目。convertView在getView中是空(null)的,第一次都是為空的,只要顯示過了convertView都不為空,會保存在Recycler中 3、當item1滾出屏幕,并且一個新的項目從屏幕低端上來時,ListView再請求一個type1視圖。convertView此時不是空值了,它的值是item1。你只需設(shè)定新的數(shù)據(jù)然后返回convertView,不必重新創(chuàng)建一個視圖,省去了inflate和findViewById的時間,性能就得到了優(yōu)化。 
了解了它的工作原理后,我們就可以重復(fù)利用convertView,只要不為空就直接使用,改變它的內(nèi)容就行了。 使用ListView的時候都會搭配一個Adapter,為了使得性能更優(yōu),ListView會緩存行item(某行對應(yīng)的View)。ListView通過Adapter的getView函數(shù)獲得每行的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<string> list = new ArrayList<string>();
-
- @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;
- }
- }
- </string></string>
復(fù)制代碼
運行效果

第一次打印的結(jié)果convertView都是為null

滑動ListView后的打印 
從上面的打印消息可以看出,Recycler中會保存七個convertView對象用來顯示Item,不管你有上千個Item,也只會創(chuàng)建顯示滿屏的convertView,這就大大節(jié)省了內(nèi)存,對viewHolder的Tag的使用也大大節(jié)省了性能開銷
|