2012-05-23 4 views
5

Próbowałem utworzyć ListView, który mogę posortować za pomocą przeciągania i upuszczania.Android ListView Przeciągnij i upuść dla Honeycomb i ICS "Błąd: Raportowanie wyniku kropli: fałsz"

Podjęto próbę postępowania zgodnie z przewodnikiem Androida here oraz z kodem źródłowym podanym na Git powyżej here. Ponadto, nie chcę używać przykładu Music app, ponieważ próbuję użyć nowych narzędzi podanych w Honeycomb i wyżej.

Do tej pory udało mi się utworzyć listę i mogę przeciągnąć elementy. Niestety, kiedy upuszczam element na listę, pojawia się następujący błąd:

"I/ViewRoot (22739): Raportowanie wyniku dropu: false".

Podejrzewam, że mój słuchacz kropli nie jest utworzony na właściwym elemencie, a więc kropla nigdy nie zostanie wywołana. Oto kod źródłowy, dziękuję bardzo za pomoc.

XML dla listy:

<?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> 

Moja listView: jeszcze nie udało się dostać do „ACTION_DROP” wydarzenie tak, że kod nie jest testowany. Właśnie coś nad czym pracowałem. Moje główne pytanie jest takie, że nigdy nie dostaję się do ACTION_DROP.

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; 
    } 
} 

Dziękuję bardzo za pomoc!

AKTUALIZACJA:

Nie mogłem zrozumieć dlaczego. Ale kiedy zmienił przełączyć sprawę do tego, wydawało się działać:

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; 

      } 

Odpowiedz

5

Twoja zmiana rozwiązaniu problemu, bo trzeba wrócić true z onDrag kiedy dostaniesz DragEvent.ACTION_DRAG_STARTED w celu dalszego otrzymywania zdarzenia przeciągania tej słuchacza. W Twojej aktualizacji zwracasz true dla tego przypadku, więc kontynuujesz odbieranie zdarzeń przeciągania i logika upuszczania działa poprawnie.

Jeśli nie zwrócisz true dla przypadku DragEvent.ACTION_DRAG_STARTED, Twój detektor nie będzie otrzymywać żadnych innych zdarzeń z wyjątkiem DragEvent.ACTION_DRAG_ENDED.