1

我有 10,000 行的数据库表,我想在列表视图中显示。我想显示前 20 个,当用户向下滚动到最后一个项目时,应该加载下一个 20(依此类推)。加载列表视图中的所有数据确实需要很多时间,所以这就是为什么我希望它首先加载 20 个数据..

在 onCreate() 方法里面的代码是:

    dbHelper = new WordDbAdapter(this);
    dbHelper.open();

    //Generate ListView from SQLite Database
    displayListView();

然后在 displayListView() 方法上的代码是这样的:

  @SuppressWarnings("deprecation")
private void displayListView() {


  final Cursor cursor = dbHelper.fetchAllWords();

  // The desired columns to be bound
  String[] columns = new String[] {
          WordDbAdapter.KEY_WORD,
          WordDbAdapter.KEY_ROWID,

  };

  // the XML defined views which the data will be bound to
  int[] to = new int[] {

    R.id.Word,
    R.id.imgStar,

  };

  // create the adapter using the cursor pointing to the desired data
  //as well as the layout information
  dataAdapter = new SimpleCursorAdapter(
    this, R.layout.word_info,
    cursor,
    columns,
    to
    );

  ListView listView = (ListView) findViewById(R.id.Diclist);
  // Assign adapter to ListView
  listView.setAdapter(dataAdapter);
listView.setOnScrollListener(new OnScrollListener(){
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        int lastInScreen = firstVisibleItem + visibleItemCount;
        if(cursor != null){

            if(lastInScreen == totalItemCount && isLoadingMore == false){
                isLoadingMore = true;

                loadedPage ++;
                new LoadWords().execute();
            }
        }
    }
    public void onScrollStateChanged(AbsListView view, int scrollState) {}
});




  listView.setOnItemClickListener(new OnItemClickListener() {
   @Override
   public void onItemClick(AdapterView<?> listView, View view,
     int position, long id) {
   // Get the cursor, positioned to the corresponding row in the result set
   Cursor cursor = (Cursor) listView.getItemAtPosition(position);


   // Get the word name from this row in the database.
       String wordSelected =
               cursor.getString(cursor.getColumnIndexOrThrow("word"));
       String wordSyllabication =
               cursor.getString(cursor.getColumnIndexOrThrow("syllabication"));
       String wordPartofSpeech =
               cursor.getString(cursor.getColumnIndexOrThrow("partofspeech"));
       String wordMeaning =
               cursor.getString(cursor.getColumnIndexOrThrow("meaning"));
       String wordSpeak =
               cursor.getString(cursor.getColumnIndexOrThrow("speakword"));

       EditText TextDic = (EditText) findViewById(R.id.TextDic);
       TextDic.setText(wordSelected);
       speakMeaning = wordMeaning;
       speakSyllabication = wordSyllabication;
       speakPartOfSpeech = wordPartofSpeech;
       speakWord = wordSpeak;
       speakGetWord = wordSelected;


       //Toast.makeText(getApplicationContext(),
             //  wordSyllabication + "\n" + wordPartofSpeech + "\n" + wordMeaning , Toast.LENGTH_SHORT).show();

       }
      });



  EditText TextDic = (EditText) findViewById(R.id.TextDic);
  TextDic.addTextChangedListener(new TextWatcher() {

   public void afterTextChanged(Editable s) {
     speakWord = "";
     speakMeaning = "";

   }

   public void beforeTextChanged(CharSequence s, int start,
     int count, int after) {
   }

   public void onTextChanged(CharSequence s, int start,
     int before, int count) {
   dataAdapter.getFilter().filter(s.toString());
   }
  });

   dataAdapter.setFilterQueryProvider(new FilterQueryProvider() {
         public Cursor runQuery(CharSequence constraint) {
         return dbHelper.fetchWordsByWord(constraint.toString());
         }
     });


     }

那么我的 AsyncTask 是这样的:

private class LoadWords extends AsyncTask<String, Void, Void> {
    private final ProgressDialog dialog = new ProgressDialog(DictionaryActivity.this);

    Cursor cursor = dbHelper.fetchAllWords();

    @Override
    protected void onPreExecute() {
       this.dialog.setMessage("Loading books...");
       this.dialog.show();
    }

    public void execute() {
        // TODO Auto-generated method stub

    }

    @Override
    protected Void doInBackground(String... arg0) {
        try{
            cursor = dbHelper.fetchAllWords();
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }
    @SuppressWarnings("deprecation")
    @Override
    protected void onPostExecute(final Void unused){
        if(cursor != null){
            if(dataAdapter == null){
                startManagingCursor(cursor);
                String[] columns = new String[] {
                          WordDbAdapter.KEY_WORD,
                          WordDbAdapter.KEY_ROWID,

                  };
                int[] to = new int[] {

                        R.id.Word,
                        R.id.imgStar,

                      };  
                getListView().setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
                dataAdapter = new SimpleCursorAdapter(DictionaryActivity.this, R.layout.word_info, cursor, columns, to);
                ListView listView = (ListView) findViewById(R.id.Diclist);
                  // Assign adapter to ListView
                listView.setAdapter(dataAdapter);


            }else{
                dataAdapter.notifyDataSetChanged();
            }
        }
        if(dialog != null && dialog.isShowing()){
            dialog.dismiss();
        }
        isLoadingMore = false;
    }

    private AbsListView getListView() {
        // TODO Auto-generated method stub
        return null;
    }
}
4

2 回答 2

2

适配器不会一次加载所有内容,这不应该是您看到性能不佳的原因。ListView 和 SimpleCursorAdapter 完全能够滚动只有 10,000 个项目的列表。适配器仅在用户滚动列表时加载项目。从您发布的代码中,我会说您的性能问题来自

dbHelper.deleteAllWords();
dbHelper.insertSomeWords();

如果您发布这些方法的代码dbHelper.fetchAllWords(),也许我们可以提供更多帮助。此外,您可以通过在后台线程上执行这些长时间运行的任务(查看AsyncTask)并使用ProgressDialog通知用户正在发生的事情来解决用户界面问题。

于 2013-02-22T16:35:51.213 回答
2

看看伟大的马克墨菲的无尽适配器。这真的很容易。您将拥有仅包含您正在显示的项目的数据集。然后,在适配器中,您可以告诉它从数据库中获取下一组并将其添加到数据集中。

于 2013-02-22T16:49:38.230 回答