3

我正在开发一个在列表视图中显示某些地方的应用程序。在每个列表视图项目中,都有一个指向该地点(酒店、酒吧等)的箭头。

问题是我不知道如何有效地更新这个箭头,而不是在本地兑现视图(根据谷歌 I/O 视频,这是我永远不应该做的事情)。

每次手机方向传感器事件都需要更新箭头,每秒更新多次。

那么有比在每个事件上调用 notifyDataSetChanged() 并重新填写每个列表项数据更好的方法吗?

更新(对于@dharan 和任何感兴趣的人):

我已经停止了这个项目的工作,因为我现在有一份全职工作,但我想到了一个解决方案(未实现/未经测试)。

首先将旋转角度限制为固定步长,(例如:5、10、15、20、... 355、360)然后缓存每个旋转角度的旋转图像,以避免昂贵的图像旋转计算(但在更高的内存成本)。

之后,我会让我的 getView() 方法知道何时只更新图像而不是所有数据。就我而言,这很简单:

public View getView(int position, View convertView, ViewGroup parent) {
     if (convertView != null && place[position].id == (Integer)convertView.getTag()){
         //the place information is already set correctly so just update the image
     }
     ...
}

在这些修改之后,我相信调用 notifyDataSetChanged() 不会导致严重的性能问题。

4

1 回答 1

2

如果您在 ListView 中没有太多项目,您可以转换为使用普通的 LinearLayout 并单独控制这些项目。LinearLayout 的问题是,如果一个项目改变了它的大小,那么所有的东西(即所有的孩子)都必须被转发出去。因此,触发一项更改也可以重新触发其他内容以进行布局。现在,因为您要更换指南针,您可能可以绕过它,因为这不会导致每一行都改变其整体尺寸。您只需要重新绘制该项目。

The other option is to write your own layout that takes some short cuts making some assumptions the general purpose layout managers can't. The last thing I might look at is what does notifyDataSetChanged() does under the covers. You might be able to extend ListView and write a method that only redraws the row that changed (of course this assumes the height of the row hasn't changed). If the row height changes then everything after that row has to be relayed out.

于 2012-05-28T19:29:44.340 回答