Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發之ListView中Adapter的優化

Android開發之ListView中Adapter的優化

編輯:關於Android編程

ListView是Android開發最常用的控件,適配器adapter是將要顯示的數據映射到View中並添加到ListView中顯示
在實現ListView時,我們需要定義適配器如BaseAdapter、ArrayAdapter、CursorAdapter、SimpleAdapter等,並且重寫其一下四個方法:
1 public int getCount();
2 public Object getItem(int position)
3 public long getItemId(int position)
4 public View getView(int position, View convertView, ViewGroup parent)


我們需要定義一個View,用來顯示每條信息,最後添加到ListView中。

比如我們定義了一個view文件:list_item_callsms.xml




    

    


我們在實現Adapter時,假設我們這樣操作:

private List infos;

private class CallSMSSafeAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			// 返回多少條
			return infos.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return 0;
		}

		//有多少個條目    這個方法就會被調用多少次
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			//把一個布局文件轉換成一個  view對象    每次都要調用  非常占用內存空間
			View view = View.inflate(getApplicationContext(),
					R.layout.list_item_callsms, null);
			TextView tv_black_number = (TextView) view
					.findViewById(R.id.tv_black_number);
			TextView tv_black_mode = (TextView) view
					.findViewById(R.id.tv_black_mode);

			tv_black_number.setText(infos.get(position).getNumber());
			String mode = "全部攔截";
			if (infos.get(position).getMode().equals("1")) {
				mode = "電話攔截";
			} else if (infos.get(position).getMode().equals("2")) {
				mode = "短信攔截";
			}

			tv_black_mode.setText(mode);
			return view;
		}

	}

上面會出現一個問題,當要顯示的數據集合超過100多條時(infos),當我們快速的滑動ListView時,界面會顯示程序無響應,而LogCat中則不停的打印DVM虛擬機GC垃圾回收數據(實際是每次定義的View對象);這樣別然嚴重的影響程序的性能和用戶體驗;


所以針對上述,可以對ListView使用的Adapter做兩方面的優化:

1、 減少內存中View對象的創建次數個數。

ListView中的View在第一個可見的列表裡是創建的(converView是為null的),當再次加載滑動時,會converView會復用之間創建的view,之後循環這個可見的View對象列表。

convertView The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).

2、減小view中對應控件查找的次數。

每次查找view中的控件都是相當耗時的,相當於遍歷了一遍view對應的xml樹,所以我們只需在第一個遍歷,以後直接復用。

因此我們可以創建一個View緩存,然後使用view的Tag存放的控件在內存中的地址。所以我們最多創建ViewList可見的長度個View,查找一次View中控件的id。

這樣就能很大的提升程序的性能。


優化後的代碼如下:

private class CallSMSSafeAdapter extends BaseAdapter {

		@Override
		public int getCount() {
			// 返回多少條
			return infos.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return 0;
		}

		//有多少個條目    這個方法就會被調用多少次
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			ViewHolder holder = null;
			
			//把一個布局文件轉換成一個  view對象    每次都要調用  非常占用內存空間
			//1. 減小內存中View對象創建的個數
			if(convertView == null){
				//converView 為空時 才創建
				convertView = View.inflate(getApplicationContext(),
						R.layout.list_item_callsms, null);
				holder = new ViewHolder();
				//2. 減小View中控件查詢的次數 
				holder.tv_number = (TextView) convertView
						.findViewById(R.id.tv_black_number);
				holder.tv_mode = (TextView) convertView
						.findViewById(R.id.tv_black_mode);
				//把ViewHolder保存在View的tag中
				convertView.setTag(holder);
				
			}else {
				//獲取View的Tag中的ViewHolder
				holder = (ViewHolder) convertView.getTag();
			}
			
			

			holder.tv_number.setText(infos.get(position).getNumber());
			String mode = "全部攔截";
			if (infos.get(position).getMode().equals("1")) {
				mode = "電話攔截";
			} else if (infos.get(position).getMode().equals("2")) {
				mode = "短信攔截";
			}

			holder.tv_mode.setText(mode);
			return convertView;
		}

	}
	
	/**
	 * 記錄View中控件的內存地址  相當於一個記事本
	 * @author zty
	 *
	 */
	static class ViewHolder{
		TextView tv_number;
		TextView tv_mode;
	}





  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved