2012-06-11 18 views
17

Tôi đang triển khai drag'n'drop cho các chế độ xem. Khi kéo được bắt đầu, tôi đặt tầm nhìn của chế độ xem để INVISIBLE, sau đó, nếu kéo bị gián đoạn - trở lại VISIBLE:java.util.ConcurrentModificationException trong View.setVisibility

public boolean onTouch(View v, MotionEvent event) { 
    if (event.getAction() == MotionEvent.ACTION_DOWN) { 
     // Skipped some code 
     boolean dragStarted = v.startDrag(data, shadowBuilder, v, 0); 

     if (dragStarted) { 
      v.setVisibility(View.INVISIBLE) 
     } 
    } 
} 

Và:

if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) { 
    View droppedView = (View) event.getLocalState(); 
    droppedView.setVisibility(View.VISIBLE); 
} 

Và khi "Kéo kết thúc" sự kiện là gọi là, tôi nhận được ngoại lệ:

E/AndroidRuntime(7118): FATAL EXCEPTION: main 
E/AndroidRuntime(7118): java.util.ConcurrentModificationException 
E/AndroidRuntime(7118):  at java.util.HashMap$HashIterator.nextEntry(HashMap.java:792) 
E/AndroidRuntime(7118):  at java.util.HashMap$KeyIterator.next(HashMap.java:819) 
E/AndroidRuntime(7118):  at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1046) 
E/AndroidRuntime(7118):  at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048) 
E/AndroidRuntime(7118):  at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048) 
E/AndroidRuntime(7118):  at android.view.ViewGroup.dispatchDragEvent(ViewGroup.java:1048) 
E/AndroidRuntime(7118):  at android.view.ViewRootImpl.handleDragEvent(ViewRootImpl.java:3471) 
E/AndroidRuntime(7118):  at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2620) 
E/AndroidRuntime(7118):  at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime(7118):  at android.os.Looper.loop(Looper.java:137) 
E/AndroidRuntime(7118):  at android.app.ActivityThread.main(ActivityThread.java:4575) 
E/AndroidRuntime(7118):  at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime(7118):  at java.lang.reflect.Method.invoke(Method.java:511) 
E/AndroidRuntime(7118):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789) 
E/AndroidRuntime(7118):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556) 
E/AndroidRuntime(7118):  at dalvik.system.NativeStart.main(NativeMethod) 

Tại sao và cách khắc phục?

+0

về lý do tại sao ngoại lệ này xảy ra khi bạn chèn hoặc xóa một số yếu tố của một iterable, khi bạn đang iterating ngày đó. nhưng có vẻ như là một con bọ trong android. –

+2

thử 'dropView.post (Runnable mới() {public void run() {droppingView.setVisibility (View.VISIBLE);}});' bạn sẽ cần phải thực hiện dropView final –

+0

chỉ là một ý tưởng, nhưng bạn đã thử API chưa trình diễn? họ có một ví dụ kéo & thả đẹp ở đó. chỉ chơi với nó và thay đổi khả năng hiển thị chính xác khi bạn muốn. kể từ khi tôi không có một thiết bị với API11 +, tôi không thể kiểm tra nếu bất cứ điều gì tôi làm giúp (giả lập là không đủ vì nó đôi khi cho kết quả sai) –

Trả lời

38

Bạn có thể thử này

if (event.getAction() == DragEvent.ACTION_DRAG_ENDED) { 
    final View droppedView = (View) event.getLocalState(); 
    droppedView.post(new Runnable(){ 
     @Override 
     public void run() { 
      droppedView.setVisibility(View.VISIBLE); 
     } 
    }); 
} 

Hình như Android bản thân cố gắng truy cập Xem trạng thái cùng một lúc như bạn kết thúc kéo.

EDIT

lời giải thích chính xác hơn. Bằng cách đặt setVisibility(), bạn đang bao gồm hoặc loại trừ View từ bộ sưu tập nội bộ của chế độ xem Android, sẽ phản hồi sự kiện kéo. Bộ sưu tập này được sử dụng trong quá trình gửi các sự kiện kéo và do đó bằng cách cố gắng setVisibility (nói cách khác là cố gắng sửa đổi người nghe các sự kiện kéo) bạn đang gây ra ConcurrentModificationException

-2

Có thể this có thể trợ giúp. ở đây trong liên kết đã cho biết: thay vì DragEvent.ACTION_DRAG_ENDED, hãy sử dụng DragEvent.ACTION_DROP.

+3

Tôi cần xử lý việc hủy drag'n'drop, khi chế độ xem không bị xóa. – arts777

Các vấn đề liên quan