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

Android之——ListView優化

編輯:關於Android編程

 

作為客戶端,其最主要的任務就是最直觀的和用戶交互。從服務器拿數據,解析過後顯示數據,根據用戶操作按照一定的協議傳回數據,達到用戶想要的結果。這是我自己的理解,所以我們的程序,必須給用戶一個良好的體驗。

listView可以說是安卓開發中很重要的一個控件。我所做的項目中,幾乎每個頁面都會有listView。Adapter是listView和數據源間的中間人。當每條數據進入可見區域時,adapter的getview()會被調用,返回代表具體數據的視圖。觸摸滾動時,頻繁調用。支持成百上千條數據。然而listView同時也很復雜,想要做好優化也不容易,下面是我自己整理的listView的優化方式

1、最簡單的方法,最慢且最不實用

 

public View getView(int pos, View convertView, ViewGroup parent){
	 View item = mInflater.inflate(R.layout.list_item, null);
	 ((TextView) item.findViewById(R.id.text)). setText(DATA[pos]);
	 ((ImageView) item.findViewButId(R.id.icon)).
	 setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
	 return item;
}
每條數據我們都會去解析布局。相當於每次都去new一個對象,寫第一個listView的時候我也是這樣寫的,功能自然能實現,但是實際上效率很低我們

 

2、可以利用convertView回收視圖,效率能提高200%

 

 public View getView(int pos, View convertView, ViewGroup parent){
	if (convertView == null) {
		convertView = mInflater.inflate( R.layout.list_item, null);
	}
	//這個地方相當於做了一個緩存機制。只有convertVIew為空的時候我們才去解析布局,因為解析布局實際上是很麻煩,很耗時的。我們只解析一次布局,其他的我們用同一個緩存的布局
	((TextView) convertView.findViewById(R.id.text)).
	setText(DATA[pos]);
	((ImageView) convertView.findViewButId(R.id.icon)).
	setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
	return convertView;
}

 

3、利用viewholder模式,效率在提高50%

 

static class ViewHolder {
	TextView text;
	ImageView icon;
}
public View getView(int pos, View convertView, ViewGroup parent){
	ViewHolder holder;
	if (convertView == null) {
		convertView = mInflater.inflate(R.layout.list_item, null);
		holder = new ViewHolder();
		holder.text = (TextView) convertView.findViewById(R.id.text));
		holder.icon = (ImageView) convertView.findViewButId(R.id.icon));
		convertView.setTag(holder);
	}else{
		holder = (ViewHolder) convertView.getTag();
	}
	holder.text.setText(DATA[pos]);
	holder.icon.setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
	return convertView;
}
以上3點是listView中常用的,當然也是最基本的優化方式。如果沒有什麼特殊要求,對於android來說這3種優化是必須存在的。還有其他的一些優化方法:

 

4、背景和圖像

視圖背景圖像總會填充整個視圖區域
1)圖像尺寸不合適會導致自動縮放
2)避免實時縮放
3)最好預先縮放到視圖大小

 originalImage = Bitmap.createScaledBitmap(
	originalImage,    // 縮放圖像
	view.getWidth(),  // 視圖寬度
	view.getHeight(), // 視圖高度
	true); // 線性過濾器
默認情況下, 窗口有一個不透明的背景
有時可以不需要
最高層的視圖是不透明的 layout_width = fill_parent
最高層的視圖覆蓋整個窗口 layout_height = fill_parent
更新看不見的背景是浪費時間

 

5、刪除窗口背景:

1)修改編碼

 

 public void onCreate(Bundle icicle){
	super.onCreate(icicle);
	setContentView(R.layout.mainview);
	// 刪除窗口背景
	getWindow().setBackgroundDrawable(null);
	...
}

 

6、修改xml

首先確定你的res/values/styles.xml有

parent=android:Theme>
然後編輯androidmainfest.xml
 android:theme=@style/NoBackgroundTheme>
   ...

 

7、更新請求

當屏幕需要更新時,調用invalidate()方法,簡單方便,但是更新了整個視圖,代價太高。
最好先找到無效區域,然後調用

invalidate(Rect dirty);
invalidate(int left, int top, int right, int bottom);

 

8、視圖和布局

如果一個窗口包含很多視圖,啟動太慢,繪制時間長,用戶界面反應速度很慢
解決方法:
1)使用textview的復合drawable減少層次

 

android:layout_width=wrap_content
android:layout_height=wrap_content
android:text=@string/hello
android:drawableLeft=@drawable/icon/>
2)使用viewstuf延遲展開視圖

 

在xml文件中定義viewstuf

 

android:inflatedId=@+id/panel_import
android:layout=@layout/progress_overlay
android:layout_width=fill_parent
android:layout_height=wrap_content
android:layout_gravity=bottom/>
在需要展開視圖時
findViewById(R.id.stub_import).setVisibility(View.VISIBLE);
// 或者
View importPanel = ((ViewStub)
findViewById(R.id.stub_import)).inflate();

 

9、使用合並中間視圖

默認情況下,布局文件的根作為一個節點,加入到父視圖中,如果使用merge可以避免根節點

http://schemas.android.com/apk/res/android>

 

10、減少android的容器布局嵌套

android的布局嵌套其實在解析的時候也是很花時間的,所以,我們在能實現功能的基礎上盡量避免很多層的嵌套。寫布局的時候養成習慣就跟我們寫java代碼一樣看到重復代碼就盡量想辦法去優化一樣。

11、使用自定義視圖

 

 class CustomView extends View {
 
	@Override
	protected void onDraw(Canvas canvas) {
	// 加入你的繪圖編碼
	}

	@Override
	protected void onMeasure(int widthMeasureSpec,
	int heightMeasureSpec) {
	// 計算視圖的尺寸
	setMeasuredDimension(widthSpecSize, heightSpecSize);

	}

}

 

12、內存分配:盡量避免在性能敏感的代碼當中創建java對象

 

測量 onmeasure()
布局onlayout()
繪圖 ondraw() dispatchdraw()
事件處理 ontouchevent() dispatchtouchevent()
adapter: getview() bindview()

 

13、管理好對象:

1)適用軟引用:內存緩存的最佳選擇
2)適用弱引用:避免內存洩露

14、內存緩存:

 

private final HashMap> mCache;
public void put(String key, T value) {
	mCache.put(key, new SoftReference(value));
}
public T get(String key, ValueBuilder builder) {
	T value = null;
	SoftReferece reference = mCache.get(key);
	if (reference != null) {
		value = reference.get();
	}
    return value;
}

 

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