Reputation: 162
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
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
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