Baseadapter's Getview Getting Wrong Position
Solution 1:
Positions aren't meant to be stable in the same way ids are. An example of this is choice modes. If your ids aren't stable, any changes in the list (moving/adding/removing items) will upset checked positions since there is really no way short of storing all items to track where each goes. Incidentally though not really related to your issue, if you DO have stable ids and an item moves more than 20 items or so, they just clear the item's checked state. At the time the code was written, I would assume they thought traversing ~20 items to check position v. id was all that could be performed in an efficient enough way.
In your case, while you may not be moving items around yourself, internally items DO move around when you call notifyDataSetChanged()
in a sense. AdapterView.AdapterDataSetObserver#onChanged shows exactly what happens when you call notifyDataSetChanged()
.
To get to the point, you can fix your issue by using stableIds instead of positions. To implement that, change your getItemId(int position)
method to return a unique id for the item at that position. Then, override hasStableIds()
to return true. Here's the docs for hasStableIds()
BaseAdapter#hasStableIds(). Now, you'll be able pass on the id to your service. You're already passing a bundle to your service, so just put the id in that. Also note that you'll need to store the ids for the items with a state you need to track. That's as simple as adding the ids to an ArrayList for example. When your service does whatever it does, it can then call your activatePlayingState
method using the id instead of a possibly stale position (remember to change that parameter from int to long). In getView
, you can then compare the activated id with the current getView item using getItemId(int position)
and setting the views for that item as expected.
Post a Comment for "Baseadapter's Getview Getting Wrong Position"