ListView動態加載數據 – Android移動開發技術文章_手機開發 Android移動開發教學課程

當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” 博客

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。