ListView 優化

1、爲什麼做優化

        說起爲什麼要對ListView這個控件做優化,這個問題還真不是那麼容易回答,因爲它要優化的原因實在是太簡單,那就是Android手機性能有限,要讓它跑起來很流暢,自然就有了優化的需求了。優化過後的應用程序,會跑得比較流暢,能夠讓用戶體驗顯著提升。

        這裏我們主要討論它需要節約時間,讓程序更加流暢。那麼問題來了,如何節約時間了,這就是一個空間換時間的問題了。


2、ListView工作原理

        如果要談優化,首先應該對ListView這個控件怎麼運行的瞭解清楚吧,這個東西不瞭解,我們談優化猶如水中撈月一樣,是個笑話。

        ListView其實是一個滑動控件,只是使用的是list集合存儲數據,顯示的方式是一個條目佔滿一行這樣的形式來的。與之類似的GrivdView也是類似的工作原理,一通則百通,類似的道理。ListView是一堆具有相同屬性的數據,展示在界面上。什麼是有規律的呢?比如,食堂的一排桌子椅子,他們就是又規律的放在一起的,只是每個桌子上坐着的人可能不一樣。如果我們把人看作數據,那麼桌子和椅子就可以看作是我們界面上的控件。

        基於上面的認識,我們會不會想到,如果是這樣的話,我們只要獲取到不同的數據,然後將控件複製多個就可以了,對不對?嗯,就是這樣的,我們看一下下面的圖示:


       上面這幅圖,是我從網上找來的,比我畫得好,我就不重複造輪子了。這裏有兩個意思,第一個是重複創建很多個item控件,第二個是,利用相同的item控件。第一個我們上面已經解說了,這裏不再贅述,我們談談第二個。這裏我們發現一個問題,那就是我們的手機屏幕大小是有限的,但是item的數據內容可能就會有很多,不只是幾條數據,幾十條數據,可能成百上千條數據。那麼,android系統中如何做優化的呢?

        原始的方式,我們只顯示這麼多控件信息,控件保持不變,變化的是數據,使用相同的控件信息,但是使用不同的數據內容。哇靠,清晰了吧!


3、簡單優化方式

       最簡單的方式是使用conentView進行緩存處理,這裏代碼如下:

		if (convertView == null) {
			convertView = LayoutInflater.from(mContext).inflate(
					R.layout.item_more_view, null);
			holder.tv_item_title = (TextView) convertView
					.findViewById(R.id.tv_item_more_title);
			holder.iv_item_home = (ImageView) convertView
					.findViewById(R.id.iv_item_more_view);
			holder.tv_item_issue = (TextView) convertView
					.findViewById(R.id.tv_item_more_issue);
			holder.progressBar = (ProgressBar) convertView
					.findViewById(R.id.bar_item_more);
			holder.tv_item_person = (TextView) convertView
					.findViewById(R.id.tv_person_item_more);
			holder.btn_item_home = (Button) convertView
					.findViewById(R.id.btn_item_more);

		} 


4、深度優化方式

       經過簡單的測試,上面的代碼,大概能優化50%左右,但是我們發現,這種優化方式還不夠,視圖的回收並不是我們所期望的最好方式,這裏我們可以把它再次緩存起來。說到底,還是一個空間換時間的思路:

ViewHolder holder = null;
		if (convertView == null) {
			holder = new ViewHolder();

			convertView = LayoutInflater.from(mContext).inflate(
					R.layout.item_more_view, null);
			holder.tv_item_title = (TextView) convertView
					.findViewById(R.id.tv_item_more_title);
			holder.iv_item_home = (ImageView) convertView
					.findViewById(R.id.iv_item_more_view);
			holder.tv_item_issue = (TextView) convertView
					.findViewById(R.id.tv_item_more_issue);
			holder.progressBar = (ProgressBar) convertView
					.findViewById(R.id.bar_item_more);
			holder.tv_item_person = (TextView) convertView
					.findViewById(R.id.tv_person_item_more);
			holder.btn_item_home = (Button) convertView
					.findViewById(R.id.btn_item_more);

			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}

這裏的ViewHolder如下所示:

/** 界面控件 */
	public final class ViewHolder {
		public TextView tv_item_title; // 標題欄
		public ImageView iv_item_home; // 商品圖片
		public TextView tv_item_issue;// 顯示第幾期
		public ProgressBar progressBar;// 進度條
		public TextView tv_item_person;// 顯示還有多少人
		public Button btn_item_home;// 搶單按鈕
	}


5、優化總結

(1)、減少findViewById()的次數,findViewById是一個相對比較耗性能的操作,它每次都需要到佈局文件中去查找空間信息,然後加載bean對象中的數據內容,顯示在界面上。

(2)、優化,其實也就是兩種,一種是時間換空間,一種空間換時間。依照現在對用戶體驗的重視,硬件資源的價格下降,大多數情況都是使用空間換時間,要讓用戶體驗更好。

(3)、緩存,優化要尤其注意緩存這個東西,它的優化是最快的。重新在內存中生成的時間遠大於直接從內存中獲取,最常見的就是數據庫的鏈接,不要經常斷開去查詢,這樣做是非常耗時的操作。

(4)、經驗,在做優化的時候,經驗也是很重要的,不過這一點在移動端並不是那麼明顯。在做服務器端開發的時候,這種經驗就非常重要,你對一個業務的熟悉,有助於你寫出更好的程序。優化並不僅僅是從程序代碼中優化,也可以從業務流程上去優化。

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