當listview需要載入的資料過多時,若一次性載入則速度會相當緩慢,影響使用者體驗,這時候就需要動態載入資料,即每次載入固定長度的資料,android market的listview就是採用這種方式,使得載入看起來很平滑,響應速度很快,有助於提高使用者體驗。
首先,要實現動態載入首先需要在擷取資料時每次在上次擷取到的資料之後的位置開始取得固定長度的資料,可通過"select * from TableName LIMIT m OFFSET n"語句實現,其中m是要取得資料的長度,n是資料的位移量。
然後,在Activity中需要重寫listview的onScroll方法,在onScroll中添加判斷條件,當上一次載入的資料顯示完並滑動到底部之後需要再次擷取資料,可以在UI Thread中在開啟一個線程去載入資料,載入資料時應彈出一個試圖提示使用者正在載入。
最後,載入資料的線程處理完畢後,重新整理ListView。
以下是實現動態載入的主要步驟:
//載入資料的方法
private void fillAdapter(int count, int begin) {
// TODO Auto-generated method stub
SQLiteOpenHelper mSQLiteOpenHelper = new SQLiteOpenHelper (
this);
Cursor c= mSQLiteOpenHelper .getDynamicListViewData(count, offset);
}
//監聽listview的onScroll方法
OnScrollListener listScroll = new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(isLoading) //正在載入時就不要讓在執行活動觸發事件
return;
if (firstVisibleItem + visibleItemCount == totalItemCount) {
// 開線程去擷取資料
if (totalItemCount <= totalItemsCount) {
Integer[] params = new Integer[] { 25, currentItemCount };
mAsynchTask = new AsynchTask();
mAsynchTask.execute(params);
} else {
Toast.makeText(EventTracker.this, "there is no data!",
Toast.LENGTH_SHORT).show();
}
}
}
};
//通過AsyncTask更方便的實現多線程管理,使得載入效果更平滑
private class AsynchTask extends AsyncTask<Integer, Void, Void> {
@Override
/**將在onPreExecute 方法執行後馬上執行,該方法運行在後台線程中。
* 這裡將主要負責執行那些很耗時的後台計算工作。可以調用 publishProgress方法
* 來更新即時的任務進度。該方法是抽象方法,子類必須實現。 */
protected Void doInBackground(Integer... params) {
fillAdapter(params[0], params[1]);
return null;
}
@Override
/** 在doInBackground 執行完成後,onPostExecute 方法將被UI thread調用,
* 背景計算結果將通過該方法傳遞到UI thread.
* */
protected void onPreExecute() {
//loadingView為自訂的一個dialog,用於提示使用者正在載入
mEventListView.addFooterView(loadingView);
isLoading=true;
}
@Override
/** 在doInBackground 執行完成後,onPostExecute 方法將被UI thread調用,
* 背景計算結果將通過該方法傳遞到UI thread.
* */
protected void onPostExecute(Void result) {
bindAdapter();
mListView.removeFooterView(loadingView);
mListView.setSelection(currentItemCount);
currentItemCount += 25;//每次載入25列,位移量也遞增25
isLoading=false;
}
}
資料庫中方法如下:
public Cursor getDynamicListViewData(int count, int offset) {
return getReadableDatabase().rawQuery(
"select * from TableName limit " + count + "offset" + offset,
null);
}
本文出自 “HDDevTeam” 部落格