如何使用Android在复杂的ListView创建上提高(感知)速度?

e-s*_*tis 1 android listview

我有一个使用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);
}
Run Code Online (Sandbox Code Playgroud)

一些事实:

  • items.fetchItemForCurrentView() 触发一个非常繁重的SQL查询

  • this.getItemPositionFromId() 循环遍历整个ListView,以查找具有给定id的行的索引.

  • item_cursor_adapter扩展SimpleCursorAdapter和覆盖

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

这是一个非常沉重的方法.

在典型的应用程序用例中,这种方法在用户需求中经常被调用,并且等待一秒钟以使屏幕刷新以降低用户体验.

你对如何改进这个有什么建议吗?

一些想法:

  • 使用线程加载数据.但是,之后如何填写清单呢?如何让它看起来不干扰屏幕?
  • 重用一些对象/使用一些我没想到的缓存.
  • 找到一种方法让列表更新而不重新加载一切
  • 更改我的游标适配器的实现.也许扩展一个更高效的父级或使用比getView更好的东西?

Com*_*are 5

你可以摆脱所有的代码并调用requery()Cursor.顾名思义,它会重新运行Cursor首先生成的查询.这将获取数据更改并通知列表适配器有关这些更改.列表适配器将更新屏幕以显示可见的行.

对于a SimpleCursorAdapter,覆盖newView()/ bindView(),或使用a ViewBinder,或使用setViewValue()和亲属,如文档中所述.您可以覆盖getView(),但是您必须自己进行行回收.