2012-05-23 29 views
5

Tôi đã cố tạo một ListView mà tôi có thể sắp xếp bằng cách kéo và thả.Android ListView Kéo và thả cho Honeycomb và ICS "Lỗi: Báo cáo kết quả thả: false"

Tôi đã cố gắng làm theo hướng dẫn Android here và một số mã nguồn được cung cấp trên Git trên here. Ngoài ra, tôi không muốn sử dụng ví dụ ứng dụng Âm nhạc vì tôi đang cố gắng sử dụng các công cụ mới được đưa ra trong Honeycomb trở lên.

Cho đến nay tôi đã thành công trong việc tạo danh sách và tôi có thể kéo các mục. Thật không may khi tôi thả mục vào danh sách tôi nhận được lỗi sau:

"I/ViewRoot (22739): Báo cáo kết quả thả: sai".

Tôi có một sự nghi ngờ rằng trình lắng nghe thả của tôi không được tạo trên đúng mục và do đó thả không bao giờ được gọi. Đây là một số mã nguồn, cảm ơn bạn rất nhiều vì sự giúp đỡ của bạn.

XML Đối với Danh mục:

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

ListView của tôi: Tôi vẫn chưa thể nhận được vào sự kiện "ACTION_DROP" vì vậy mã mà không được kiểm tra. Chỉ là điều tôi đang làm. Câu hỏi chính của tôi là tôi chưa bao giờ tham gia vào 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; 
    } 
} 

Cảm ơn bạn rất nhiều vì đã giúp bạn!

CẬP NHẬT:

Tôi không thể hiểu tại sao. Nhưng khi tôi đã thay đổi chuyển trường hợp này, nó dường như làm việc:

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; 

      } 

Trả lời

5

cập nhật của bạn khắc phục vấn đề bởi vì bạn phải trở true từ onDrag khi bạn nhận được DragEvent.ACTION_DRAG_STARTED để tiếp tục nhận được sự kiện kéo để nghe đó. Trong bản cập nhật, bạn trả lại true cho trường hợp này, vì vậy bạn tiếp tục nhận các sự kiện kéo và logic thả hoạt động chính xác.

Nếu bạn không trả lại true cho trường hợp DragEvent.ACTION_DRAG_STARTED, người nghe của bạn sẽ không nhận được bất kỳ sự kiện nào khác ngoại trừ DragEvent.ACTION_DRAG_ENDED.