I have a HashMap
that gets created in my method
final HashMap<Long, Rect> listViewItemBounds = new HashMap<Long, Rect>();
that saves all the bounds of visible views in a ListView
for (int i = 0; i < getChildCount(); ++i) {
View child = getChildAt(i);
if(child != null){
int position = firstVisiblePosition+i;
long itemID = adapter.getItemId(position);
Rect startRect = new Rect(child.getLeft(), child.getTop(), child.getRight(),child.getBottom());
listViewItemBounds.put(itemID, startRect);
listViewItemDrawables.put(itemID, getBitmapDrawableFromView(child));
}
}
then I start an OnPreDrawListener
on the ListView
final ViewTreeObserver observer = getViewTreeObserver();
observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
.
.
.
}
)};
and in the onPreDrawListener I loop through he hashmap to get the bounds of the saved views
for (Long itemId: listViewItemBounds.keySet()) { //points here
.
.
.
istViewItemBounds.remove(itemId);
}
the problem comes when I change/update the adapter where all this gets called again and onPreDraw
is currently looping through the hashmap while it is being updated again due to the adapter change.
So how can I prevent the concurrency here so I dont get ConcurrentModificationException
?
Stacktrace:
08-31 19:09:41.398 29127-29127/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:792)
at java.util.HashMap$KeyIterator.next(HashMap.java:819)
at com.tyczj.myapp.views.HeaderGridView$3.onPreDraw(HeaderGridView.java:511)
at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:680)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1842)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Edit:
Iterator<Long> it = listViewItemBounds.keySet().iterator();
while(it.hasNext()){
long itemId = it.next(); //error
}