Reputation: 596753
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 query
this.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 overrides
public 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 :
Upvotes: 1
Views: 919
Reputation: 1006744
You could get rid of all that code and just call requery()
on the Cursor
. As the name suggests, it re-runs the query that generated the Cursor
in the first place. That will pick up the data changes and notify your list adapter about those changes. Your list adapter will update the screen for whichever rows are visible.
For a SimpleCursorAdapter
, either override newView()
/bindView()
, or use a ViewBinder
, or use setViewValue()
and kin, as described in the documentation. You can override getView()
, but then you have to do your own row-recycling stuff.
Upvotes: 5