如何提高(感知)使用 Android 创建复杂 ListView 的速度?
Posted
技术标签:
【中文标题】如何提高(感知)使用 Android 创建复杂 ListView 的速度?【英文标题】:How can I improve (perceived) speed on a complex ListView creation with Android? 【发布时间】:2010-11-21 20:43:18 【问题描述】:我有一个使用 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 上逐行循环以查找具有给定 id 的行的索引。
item_cursor_adapter
扩展了 SimpleCursorAdapter 并覆盖了
public View getView(int position, View convertView, ViewGroup parent)
这是一个相当繁重的方法。
此方法在典型应用程序用例中经常根据用户需求调用,等待屏幕刷新会降低用户体验。
您对如何改进有什么建议吗?
一些想法:
使用线程加载数据。但是,之后如何补充列表呢?如何让它在屏幕上看起来不打扰? 重用一些对象/使用一些我没有想到的缓存。 找到一种无需重新加载所有内容即可更新列表的方法 更改光标适配器的实现。也许扩展一个更高效的父级或使用比 getView 更好的东西?【问题讨论】:
【参考方案1】:您可以摆脱所有这些代码,只需在Cursor
上调用requery()
。顾名思义,它首先重新运行生成Cursor
的查询。这将获取数据更改并通知您的列表适配器这些更改。您的列表适配器将更新屏幕上可见的行。
对于SimpleCursorAdapter
,要么覆盖newView()
/bindView()
,要么使用ViewBinder
,或者使用setViewValue()
和kin,如documentation 中所述。你可以覆盖getView()
,但是你必须自己做行回收。
【讨论】:
嗨,谢谢 newView()/bindView(),我会试试的。我忘了说我不能使用 requery() 因为一个完全不同的 SQL 查询生成时间。【参考方案2】:使用游标适配器代替基本适配器和数组适配器
【讨论】:
以上是关于如何提高(感知)使用 Android 创建复杂 ListView 的速度?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Camera 2 API Android 提高捕获图像的质量?
Android LifeCycles之让组件感知生命周期的使用(生命周期观察者)