Как я могу улучшить (воспринимать) скорость создания сложного ListView с Android? - PullRequest
1 голос
/ 22 августа 2009

У меня есть приложение, использующее ListView в качестве основного экрана. Каждая строка отображает некоторый текст, флажок и изображения в соответствии с данными, и, поскольку вы не можете сделать это с помощью стандартного ListAdapter, я создал свой собственный.

Каждый раз, когда происходит изменение (добавление / удаление строки, проверка подсказки, навигация и т. Д.) К данным списка, я обновляю отображение списка, используя этот метод:

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

Некоторые факты:

  • items.fetchItemForCurrentView() запускает очень тяжелый запрос SQL

  • this.getItemPositionFromId() цикл по всей строке ListView строка за строкой, чтобы найти индекс строки с заданным идентификатором.

  • item_cursor_adapter расширяет SimpleCursorAdapter и переопределяет

    public View getView (int position, View convertView, ViewGroup parent)

Это довольно тяжелый метод.

Этот метод вызывается по требованию пользователя довольно часто в типичном случае использования приложения, и ожидание секунды для обновления экрана снижает пользовательский опыт.

Есть ли у вас какие-либо предложения о том, как это можно улучшить?

Некоторые идеи:

  • Использование потоков для загрузки данных. Но как потом пополнить список? Как сделать так, чтобы это не мешало на экране?
  • Сделайте повторное использование некоторых объектов / используйте кеш, о котором я не думал.
  • Найдите способ обновления списка без перезагрузки ВСЕГО
  • Измените мою реализацию адаптера курсора. Может быть, расширяет возможности более эффективного родителя или использует что-то лучше, чем getView?

Ответы [ 2 ]

5 голосов
/ 22 августа 2009

Вы можете избавиться от всего этого кода и просто набрать requery() на Cursor. Как следует из названия, он заново запускает запрос, который сгенерировал Cursor. Это подберет изменения данных и уведомит адаптер списка об этих изменениях. Адаптер списка обновит экран для всех видимых строк.

Для SimpleCursorAdapter либо переопределите newView() / bindView(), либо используйте ViewBinder, либо используйте setViewValue() и kin, как описано в документации . Вы можете переопределить getView(), но тогда вам придется делать свои собственные вещи по переработке строк.

0 голосов
/ 05 июня 2013

использовать адаптер курсора вместо базового адаптера и адаптера массива

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...