使用Endless适配器的Listview

时间:2013-02-22 16:24:17

标签: java android

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

in 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;
    }
}

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:2)

看看伟大的马克墨菲的Endless Adapter。它让它变得非常简单。您将拥有仅包含您正在显示的项目的数据集。然后,在适配器中,您可以告诉它从数据库中获取下一组并将其添加到数据集中。