Bite code
Bite code

Reputation: 596753

How can I improve (perceived) speed on a complex ListView creation with Android?

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 :

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

Answers (2)

kranti
kranti

Reputation: 93

use cursor adapter instead of base adapter and array adapter

Upvotes: 0

CommonsWare
CommonsWare

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

Related Questions