2012-03-29 7 views
1

Was meine app tut, ist ganz einfach:Android Drag & Drop Bild Absturz auf ICS (4.0.3)

Es zeigt die Miniaturbilder aller Bilder auf der SD-Karte auf einem Gridview und ein Symbol an der Ecke diese Thumbnails, so dass der Benutzer es berühren kann, um einen Schatten des Bildes zu ziehen.

Dieser Schatten kann auf Ansichten gelöscht werden, für die ein Drag-Listener festgelegt wurde. Wenn das auftritt, wird eine neue Absicht mit dem Bilddateipfad Uri als Extra für die neue Absicht aufgerufen. So weit, ist es gut.

Das Problem passiert, wenn ich den Schatten auf Ansichten fallen lassen, die keine Drag Listener haben, schließlich den Bildschirm einfrieren und das mobile Gerät abstürzen!

Alles, was ich in der Stack-Trace erhalte, ist dies:

03-29 14:24:14.803: I/ViewRootImpl(2496): Reporting drop result: false 
03-29 14:24:14.803: W/WindowManager(274): Drag is in progress but there is no drag window handle. 
03-29 14:24:15.062: I/ViewRootImpl(2496): Reporting drop result: false 
03-29 14:24:15.062: W/WindowManager(274): Drag is in progress but there is no drag window handle. 
03-29 14:24:15.294: I/ViewRootImpl(2496): Reporting drop result: false 
03-29 14:25:06.972: I/Process(274): Sending signal. PID: 274 SIG: 3 
03-29 14:25:06.972: I/dalvikvm(274): threadid=3: reacting to signal 3 
03-29 14:25:07.092: I/dalvikvm(274): Wrote stack traces to '/data/anr/traces.txt' 
03-29 14:25:10.012: W/ActivityManager(274): Timeout of broadcast BroadcastRecord{2c09ce28 android.intent.action.TIME_TICK} - [email protected]2bf0c4e8, started 10009ms ago 
03-29 14:25:10.012: W/ActivityManager(274): Receiver during timeout: BroadcastFilter{2bf0cd08 ReceiverList{2bf0c660 274 system/1000 local:2bf0c4e8}} 
03-29 14:25:20.022: W/ActivityManager(274): Timeout of broadcast BroadcastRecord{2c09ce28 android.intent.action.TIME_TICK} - [email protected]2bef04e8, started 10008ms ago 
03-29 14:25:20.022: W/ActivityManager(274): Receiver during timeout: BroadcastFilter{2bef0760 ReceiverList{2bef06e8 274 system/1000 local:2bef04e8}} 
03-29 14:25:37.092: W/Watchdog(274): WATCHDOG PROBLEM IN SYSTEM SERVER: com.android.server.wm.WindowManagerService 
03-29 14:25:37.102: I/Process(274): Sending signal. PID: 274 SIG: 3 
03-29 14:25:37.102: I/dalvikvm(274): threadid=3: reacting to signal 3 
03-29 14:25:37.182: I/dalvikvm(274): Wrote stack traces to '/data/anr/traces.txt' 
03-29 14:25:37.192: I/Process(274): Sending signal. PID: 475 SIG: 3 
03-29 14:25:37.192: I/dalvikvm(475): threadid=3: reacting to signal 3 
03-29 14:25:37.202: I/dalvikvm(475): Wrote stack traces to '/data/anr/traces.txt' 
03-29 14:25:39.204: I/Watchdog_N(274): dumpKernelStacks 
03-29 14:25:39.492: I/CrashMonitor(1186): CrashMonitorService: invokeService: android.intent.action.DROPBOX_ENTRY_ADDED 
03-29 14:25:39.492: W/Watchdog(274): *** WATCHDOG KILLING THE SYSTEM: com.android.server.wm.WindowManagerService 

Meine Adapterklasse (wobei i ausführen view.startDrag() -Methode):

public class ImageCursorAdapter extends CursorAdapter { 

    private LayoutInflater mInflater; 
    private final static int mImageColumnID = 0; 
    private Options mOptions = new Options();; 
    private Cursor mCursor; 

    public ImageCursorAdapter(Context context, Cursor c) { 
     super(context, c); 

     mInflater = LayoutInflater.from(context); 
     mOptions.inSampleSize = 4; 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     mCursor = cursor; 
     ViewHolder holder = (ViewHolder) view.getTag(); 
     ImageThumbnailLoader imageLoader = new ImageThumbnailLoader(
      holder.thumbImg, cursor.getLong(mImageColumnID), 
      context.getContentResolver(), false); 
     imageLoader.execute(); 
//  holder.thumbImg.setImageBitmap(MediaStore.Images.Thumbnails.getThumbnail(
//     context.getContentResolver(), cursor.getLong(mColumnID), 
//     MediaStore.Images.Thumbnails.MICRO_KIND, mOptions)); 
     holder.dragImg.setTag(holder.thumbImg); 
     holder.dragImg.setId(cursor.getPosition()); 
     holder.dragImg.setOnTouchListener(new OnTouchListener() { 

      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       int action = event.getAction(); 
       if (action == MotionEvent.ACTION_DOWN) { 
        mCursor.moveToPosition(v.getId()); 
        int dataColumn = mCursor.getColumnIndex(MediaStore.Images.Media.DATA); 
        ClipData dragData = ClipData.newPlainText("filename", 
         mCursor.getString(dataColumn)); 
        DragShadowBuilder shadow = new DragShadowBuilder((View) v.getTag()); 
        return v.startDrag(dragData, shadow, null, 0); 
       } 
       return false; 
      } 
     }); 
     Log.i("Prototype", "bindView : " + cursor.getPosition()); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) { 
     Log.i("Prototype", "newView : " + cursor.getPosition()); 
     View view = mInflater.inflate(R.layout.grid_item, null); 
     ViewHolder holder = new ViewHolder(view); 
     view.setTag(holder); 
     return view; 
    } 


    private static class ViewHolder { 
     ImageView thumbImg, dragImg; 

     ViewHolder(View base) { 
      thumbImg = (ImageView) base.findViewById(R.id.thumbImage); 
      dragImg = (ImageView) base.findViewById(R.id.dragImage); 
     } 
    } 

} 

Irgendwelche Ideen/Hinweise auf welche ` geht hier vor? Ich würde wirklich eine Hand an dieser Sache schätzen.

Vielen Dank im Voraus.

Antwort

1

Wenn Sie in Ihrer 'onDrag (View v, DragEvent Ereignis)' Methode eine switch case-Anweisung haben, dann fügen Sie dort die 'DragEvent.ACTION_DRAG_LOCATION' -Frage hinzu. Dort können Sie festlegen, was passiert, wenn Ihr Symbol/Bild auf ein Nicht-Drag-Feld platziert wird. Hier

ein Beispiel:

public class MyDragListener implements OnDragListener { 

    @Override 
    public boolean onDrag(View v, DragEvent event) { 
    int action = event.getAction(); 
    switch (action) { 
    case DragEvent.ACTION_DRAG_STARTED: 
     break; 
    case DragEvent.ACTION_DRAG_ENTERED: 
     break; 
    case DragEvent.ACTION_DRAG_EXITED: 
     break; 
    case DragEvent.ACTION_DROP: 
     View view = (View) event.getLocalState(); 
     ViewGroup owner = (ViewGroup) view.getParent(); 
     owner.removeView(view); 
     RelativeLayout container = (RelativeLayout) v; 
     container.addView(view); 
     view.setVisibility(View.VISIBLE); 
     break; 
    case DragEvent.ACTION_DRAG_ENDED: 
        break; 
    case DragEvent.ACTION_DRAG_LOCATION: 
     view.setVisibility(View.VISIBLE); 
     break; 
    } 
    } 

} 
+0

Ich habe dies auf meiner Klasse implementiert und die Freezes auftreten immer noch. Es passiert nicht immer, nur wenn ich versuche, ein Symbol wiederholt zu ziehen ... – ImNotAnUser

+0

@ImNotAnUser Haben Sie das jemals herausgefunden? – DJayC

+0

@DJayC Nein, habe ich nicht. Ich habe mein eigenes Drag & Drop-Framework implementiert. – ImNotAnUser

1

ich ein ähnliches Problem, dass angetroffen habe ich nicht ein Layout will die Drop-Aktion zu übernehmen.

Fügen Sie einen Drag-Listener über den setOnDragListener in Ihre Ansicht ein.

view.setOnDragListener (neu MyDragListener());

Überprüfen Sie, ob die Zielansicht im onDrag-Ereignis die erforderliche Ansicht ist. Wenn die Bedingung falsch ist, geben Sie den gewünschten Code dort ein.

class MyDragListener implements OnDragListener { 

@Override 
public boolean onDrag(View v, DragEvent event) { 

    switch (event.getAction()) { 
    case case DragEvent.ACTION_DROP: 
     //check whether it has not been dropped onto your view 
      if(v!=view) 
       //your code here 
}