I have an app using a ListView as a main screen. Each row displays some text, a checkbox and images according to the data, and since you can't do that with a standard ListAdapter, I crafted my own.
Every time a change occur (adding / removing a row, checking a tip, navigating, etc) to the list data, I refresh the list display, using this method :
public void refreshList()
{
// fetch the new items
ItemDbHelper items = new ItemDbHelper(this);
Cursor item_cursor = items.fetchItemForCurrentView(this.current_context_filter);
// do not use "start managing cursor" here or resume() won't work
// anymore since the cursor will be closed despite we still need it
// set the welcome message if no items to display
if (item_cursor.getCount() == 0)
{
TextView message = (TextView) this.findViewById(R.id.home_message);
message.setVisibility(View.VISIBLE);
}
ListView list = this.task_list;
ItemListAdapter item_cursor_adater = (ItemListAdapter) list.getAdapter();
// close the old cursor manually and replace it with the new one
item_cursor_adater.getCursor().close();
item_cursor_adater.changeCursor(item_cursor);
// reset some cache data in the adapter
item_cursor_adater.reset();
// tell the list to refresh
item_cursor_adater.notifyDataSetChanged();
// to easy navigation, we set the focus the last selected item
// set the last modified item as selected
int selected_index = this.getItemPositionFromId(list,
this.getCurrentContextFilter()
.getSelectedTaskId());
list.setSelection(selected_index);
}
Some facts :
items.fetchItemForCurrentView()
triggers a very heavy SQL querythis.getItemPositionFromId()
loop on the entire ListView row by row to find the index of row with a given id.the
item_cursor_adapter
extends SimpleCursorAdapter and overridespublic View getView(int position, View convertView, ViewGroup parent)
Which is a pretty heavy method.
This method is called on the user demand quite often in the typical application use case, and waiting a second for the screen to refresh lower the user experience.
Do you have any suggestion on how this could be improved ?
Some ideas :
- Use threads to load the data. But then, how to feed up the list afterwards ? How to make it appear not disturbing on the screen ?
- Make reuse of some objects / use some cache I didn't think of.
- Find a way for the list to update without reloading EVERYTHING
- Change my implementation of the cursor adapter. Maybe extends a more efficient parent or use something better than getView ?