简体   繁体   中英

android listview with real-time sensor updates

I am working on a app that shows some places in a listview. In every listview item there is a arrow pointing towards the place(hotel, bar etc).

The problem is I don't know how to keep this arrow updated efficiently, without cashing views locally( which, according to a Google I/O video, is something i should never ever do).

The arrow needs to be updated on every phone orientation sensor event, which is many times a second.

So is there a better approach than calling notifyDataSetChanged() on every event and refiling every list item data?

UPDATE (for @dharan and anyone interested):

I have stopped working on this project because I have a full-time job now, but I thought of a solution (unimplemented/untested).

First limit the angle of rotation to a fixed step, (eg: 5, 10, 15, 20, ... 355, 360) then cache the rotated image for each angle of rotation in order to avoid expensive image rotation calculations (but at a higher memory cost).

After that I would make my getView() method know when to only update the image instead of all the data. In my case this is as easy as:

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
     }
     ...
}

After these modifications I believe that calling notifyDataSetChanged() should not cause serious performance issues.

If you don't have too many items in the ListView you could convert to using a plain LinearLayout and control those items individually. The problem with LinearLayout though is if an item changes its size then everything (ie all children) has to be relayed out. So triggering a change in one item can re-trigger other things to layout as well. Now because you're changing a compass needle you might be able to skirt around it because that shouldn't cause each row to change its overall size. You just need to repaint that item.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM