2012-05-23 1 views
5

Ich habe versucht, eine ListView zu erstellen, die ich per Drag & Drop sortieren kann.Android ListView Drag & Drop für Honeycomb und ICS "Fehler: Reporting drop result: false"

Ich habe versucht, die Android-Anleitung here und einige Quellcode auf Git über here zur Verfügung gestellt. Außerdem möchte ich das Beispiel der Music-App nicht verwenden, da ich versuche, die neuen Tools von Honeycomb und up zu verwenden.

Bis jetzt war ich erfolgreich beim Erstellen der Liste und ich kann die Elemente ziehen. Wenn ich den Artikel auf die Liste setze, erhalte ich leider folgende Fehlermeldung:

"I/ViewRoot (22739): Meldung drop result: false".

Ich habe den Verdacht, dass meine Drop-Listener nicht auf dem richtigen Element erstellt und damit der Tropfen nie aufgerufen wird. Hier ist ein Quellcode, vielen Dank für Ihre Hilfe.

XML für die Liste:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/dropTarget" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:layout_weight="1"> 
    <ListView 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:id="@android:id/list" > 
    </ListView> 
</LinearLayout> 

Mein listview: Ich habe noch nicht gelungen, in „ACTION_DROP“ Ereignis zu erhalten, so dass der Code nicht getestet. Nur etwas, an dem ich gerade arbeitete. Meine Hauptfrage ist, dass ich nie in ACTION_DROP komme.

public class procedureListView extends ListActivity { 
    private ListView mListView = null; 
    private ArrayAdapter<String> mArrayAdapter = null; 
    private View layoutDropArea = null; 

    public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.list); 

      String[] countries = getResources().getStringArray(R.array.arrayOfStuff); 
      mArrayAdapter = new ArrayAdapter<String>(this, R.layout.list_item, countries); 
      setListAdapter(mArrayAdapter); 

      mListView = getListView(); 
      mListView.setTextFilterEnabled(true); 

      layoutDropArea = findViewById(R.id.dropTarget); 

      setupDragDrop(); 
    } 
    /** 
    * Setup what to do when we drag list items 
    */ 
    public void setupDragDrop(){ 
     mListView.setOnItemLongClickListener(new OnItemLongClickListener() { 
      public boolean onItemLongClick(AdapterView<?> arg0, View v, int position, long arg3){ 
       String value = (String) ((TextView) v).getText(); 
       ClipData data = ClipData.newPlainText("procedure", value); 
       v.startDrag(data, new mDragShadowBuilder(v), null, 0);   
       return true; 
      } 
     }); 
     myDragListener mDragListener = new myDragListener(); 
     //mListView.setOnDragListener(mDragListener); 

     layoutDropArea.setOnDragListener(mDragListener); 



    } 
    protected class myDragListener implements OnDragListener{ 

     public boolean onDrag(View v, DragEvent event) { 
      final int action = event.getAction(); 
      switch (action) { 
       case DragEvent.ACTION_DRAG_ENTERED: 
        v.setBackgroundColor(Color.GRAY); 
        break; 
       case DragEvent.ACTION_DRAG_EXITED: 
        v.setBackgroundColor(Color.TRANSPARENT); 
        break; 
       case DragEvent.ACTION_DRAG_STARTED: 
        break; 
       case DragEvent.ACTION_DRAG_LOCATION: 
        v.setVisibility(View.VISIBLE); 
       // return processDragStarted(event); 
       case DragEvent.ACTION_DROP: 
        v.setBackgroundColor(Color.TRANSPARENT); 
        int newPosition = mListView.getPositionForView(v); 
        if (newPosition != ListView.INVALID_POSITION) 
         return processDrop(event, newPosition); 
        else 
         return false; 
      } 
      return false; 
     } 

    } 

    private boolean processDrop(DragEvent event, int newPosition) { 
     ClipData data = event.getClipData(); 
     if (data != null) { 
      if (data.getItemCount() > 0) { 
       Item item = data.getItemAt(0); 
       String value = item.toString(); 
       updateViewsAfterDropComplete(value, newPosition); 
       return true; 
      } 
     } 
     return false; 
    } 
    private void updateViewsAfterDropComplete(String listItem, int index) { 
     Log.d("InsertItem", "Position: "+ index); 
     mArrayAdapter.insert(listItem, index); 
     mArrayAdapter.notifyDataSetChanged(); 
    } 
    private boolean processDragStarted(DragEvent event) { 
     ClipDescription clipDesc = event.getClipDescription(); 
     if (clipDesc != null) { 
      return clipDesc.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN); 
     } 
     return false; 
    } 
} 

Vielen Dank für Ihre Hilfe!

UPDATE:

Ich kann nicht ganz herausfinden, warum. Aber wenn ich Fall zu diesem Schalter geändert, so schien es zu funktionieren:

switch (action) { 
       case DragEvent.ACTION_DRAG_ENTERED: 
        //v.setBackgroundColor(Color.GRAY); 
        return false; 

       case DragEvent.ACTION_DRAG_EXITED: 
        //v.setBackgroundColor(Color.TRANSPARENT); 
        return true; 

       case DragEvent.ACTION_DRAG_STARTED: 
        return true; 

       case DragEvent.ACTION_DRAG_LOCATION: 
        //v.setVisibility(View.VISIBLE); 
        return false; 
       // return processDragStarted(event); 
       case DragEvent.ACTION_DROP: 
        v.setBackgroundColor(Color.TRANSPARENT); 
        int newPosition = mListView.pointToPosition((int)(event.getX()),(int) event.getY()); 
        Log.d("Position", Integer.toString(newPosition)); 
        if (newPosition != ListView.INVALID_POSITION) 
         return processDrop(event, newPosition); 
        else 
         return false; 
       default: 
        return true; 

      } 

Antwort

5

Ihr Update behoben das Problem, weil Sie haben true von onDrag zurückzukehren, wenn Sie DragEvent.ACTION_DRAG_STARTED erhalten, um diese Zuhörer drag Ereignisse weiterhin erhalten. In Ihrem Update geben Sie true für diesen Fall zurück, so dass Sie weiterhin Drag-Ereignisse empfangen und die Drop-Logik ordnungsgemäß funktioniert. Wenn Sie true für den Fall DragEvent.ACTION_DRAG_STARTED nicht zurückgeben, erhält Ihr Listener keine anderen Ereignisse als DragEvent.ACTION_DRAG_ENDED.