Jin
Jin

Reputation: 162

Listview using Endless adapter

I have DB table with 10,000 rows which I want to display in the listview. I want to display first 20 and when the user scrolls down to the last item the next 20 should be loaded (and so on.). it really takes a lot of time to load all the datas in the listview so thats why i want it to load 20 datas first..

inside onCreate() Method the code is:

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

    //Generate ListView from SQLite Database
    displayListView();

then on the displayListView() method the code is like this:

  @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());
         }
     });


     }

then my AsyncTask is like this:

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

Upvotes: 1

Views: 473

Answers (2)

Wenger
Wenger

Reputation: 989

Take a look at Endless Adapter from the great Mark Murphy. It makes it really easy. You'll have your dataset that contains just the items you're displaying. In the adapter you can then tell it to grab the next set from your database and add it to the dataset.

Upvotes: 2

Samuel
Samuel

Reputation: 17171

The adapter doesn't load everything at once, and that should not be the reason you're seeing poor performance. ListView and SimpleCursorAdapter are fully capable of scrolling a list of only 10,000 items. The adapter only loads items as the user scrolls through the list. From the code that you've posted, I would say that your performance issues come from

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

If you post the code for these methods and dbHelper.fetchAllWords(), perhaps we can offer more help. Additionally, you can solve user interface problems by executing these long running tasks on a background thread (check out AsyncTask) and using a ProgressDialog to inform the user what is going on.

Upvotes: 2

Related Questions