2011-03-25 104 views
8

您好我正在嘗試拖放一個ListView。它效果很好。但是我失去了點擊和滾動的能力。如何保留這兩個?我一直在想,拖放應該發生在長時間按下該項目而不是正常的按下。這是我onTouch是位於MyListView擴展的ListViewandroid滾屏拖放

@Override 
    public boolean onTouchEvent(MotionEvent ev) { 
     final int action = ev.getAction(); 
     final int x = (int) ev.getX(); 
     final int y = (int) ev.getY(); 

     if (action == MotionEvent.ACTION_DOWN && x < this.getWidth()/4) { 
      this._dragMode = true; 
     } 

     if (!this._isDragNDrop) 
      return super.onTouchEvent(ev); 

     switch (action) { 
      case MotionEvent.ACTION_DOWN: 
       this._startPosition = pointToPosition(x,y); 
       if (this._startPosition != INVALID_POSITION) { 
        int mItemPosition = this._startPosition - getFirstVisiblePosition(); 
        this._dragPointOffset = y - getChildAt(mItemPosition).getTop(); 
        this._dragPointOffset -= ((int)ev.getRawY()) - y; 
        startDrag(mItemPosition,y); 
        drag(x,y); 
       } 
       break; 
      case MotionEvent.ACTION_MOVE: 
       drag(x,y); 
       break; 
      case MotionEvent.ACTION_CANCEL: 
      case MotionEvent.ACTION_UP: 
      default: 
       this._dragMode = false; 
       //_isDragNDrop = false; 
       this._endPosition = pointToPosition(x,y); 
       stopDrag(this._startPosition - getFirstVisiblePosition()); 
       if (this._dropListener != null && this._startPosition != INVALID_POSITION && this._endPosition != INVALID_POSITION) 
        this._dropListener.onDrop(this._startPosition, this._endPosition); 
       break; 
     } 
     return true; 
    } 

回答

5

我剛剛實施的阻力,並通過長按某個項目在我的應用程序下拉列表視圖中,拖動開始。

源代碼位於下載的GitHub:DraggableListView,我有一個blog post來形容它。希望它可以幫助你。

+0

哇,非常感謝你!我們決定推遲此功能,因爲我們無法實現此功能。我會看看這個,看看這是否解決了我的問題。我看到你的博客,它的真實需要一週時間,因爲當我滾到兩天,我不得不放棄:) – dropsOfJupiter 2011-04-18 01:51:47

+0

偉大的組件!對我來說工作得很好...... THX – kyp 2011-11-16 15:20:50

+0

上面的博客帖子鏈接不起作用,但你可以在這裏找到剩下的所需:http://codegarage.no-ip.co.uk/snippets/94 – mpemburn 2014-02-17 18:58:40

2

查看這個question獲得更多幫助。我也有一個名爲DragSortListView的組件,我花了很長時間來完善。你可以在這裏找到它:

我可以幫助你整合長按啓動了我的上述回購的叉拖動。

+0

酷庫:) – 2017-11-04 17:13:25

3

我正在實現類似的東西。 希望這會幫助別人,因爲我仍然在糾結。

... 
thumb.setOnDragListener(new Drag()); 
... 

public class Drag implements OnDragListener{ 
public static int PositionOfDraggedItem = -1; 
     public int PositionOfItemDraggedOver = -1; 

public Drag() {} 

@Override 
public boolean onDrag(View v, DragEvent event) 
{ 
    final int action = event.getAction(); 
    boolean state = true; 

    View root = v.getRootView(); 
    ListView List = (ListView) root.findViewById(android.R.id.list); 
    Object holder = v.getTag() instanceof OrderHolder? (OrderHolder)v.getTag() : v.getTag(); 

    String BookId = holder instanceof OrderHolder? String.valueOf(((OrderHolder)holder).id) : (String)holder; 

    switch(action) 
    { 
     case DragEvent.ACTION_DRAG_STARTED: 

      break; 
     case DragEvent.ACTION_DRAG_ENTERED: 
      if(PositionOfDraggedItem != -1) 
      { 
       if(this.PositionOfItemDraggedOver != PositionOfDraggedItem) 
       { 
        if(v.getBackground() != null) 
         v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row_ovr)); 
       } 
      } 
      break; 
     case DragEvent.ACTION_DRAG_LOCATION: 
      /** 
      * Set the item being 
      * here, as it will not 
      * provide location data 
      * anywhere else 
      */ 
      if(PositionOfDraggedItem == -1) 
       PositionOfDraggedItem = List.getPositionForView(v); 

      /** 
      * Set the view thats 
      * being dragged over 
      */ 
      this.PositionOfItemDraggedOver = List.getPositionForView(v); 

      int PositionOfLastVisibleView = List.getLastVisiblePosition(); 
      int PositionOfFirstVisibleView = List.getFirstVisiblePosition(); 

      if(this.PositionOfItemDraggedOver != -1 && (this.PositionOfItemDraggedOver != PositionOfDraggedItem)){ 
       if(this.PositionOfItemDraggedOver == PositionOfLastVisibleView-1 || this.PositionOfItemDraggedOver == PositionOfLastVisibleView || this.PositionOfItemDraggedOver == PositionOfLastVisibleView+1){ 
        List.smoothScrollToPosition(PositionOfLastVisibleView+1); 
       }else if(this.PositionOfItemDraggedOver == PositionOfFirstVisibleView-1 || this.PositionOfItemDraggedOver == PositionOfFirstVisibleView+1 || this.PositionOfItemDraggedOver == PositionOfFirstVisibleView){ 
        List.smoothScrollToPosition(PositionOfFirstVisibleView-1); 
       } 
      } 
      break; 
     case DragEvent.ACTION_DRAG_EXITED: 
      if(v.getBackground() != null) 
       v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row)); 
      break; 
     case DragEvent.ACTION_DROP: 
      if(event != null) 
      { 
       ClipData data = event.getClipData(); 
       if(data != null && data.getItemCount() > 0) 
       { 
        if(!data.getItemAt(0).getText().toString().equalsIgnoreCase(BookId)) 
        { 
         if(v.getBackground() != null) 
          v.setBackgroundDrawable(v.getContext().getResources().getDrawable(drawable.row)); 
         /** 
         * Ordering info for 
         * book being dragged 
         */ 
         String oShelfOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_SHELFORDER, 
           booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(data.getItemAt(0).getText().toString())); 
         String oBookOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_BOOKSORDER, 
           booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(data.getItemAt(0).getText().toString())); 

         /** 
         * Ordering info 
         * for book being dragged 
         * to 
         */ 
         String dShelfOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_SHELFORDER, 
           booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(BookId)); 
         String dBookOrder = BookManager.item(v.getContext().getContentResolver(), dbhelper.BOOKS_BOOKSORDER, 
           booksprovider.GetUri(dbhelper.BOOKS), Long.parseLong(BookId)); 

         /** 
         * Update book being dragged 
         */ 
         ContentValues args = new ContentValues(); 
         args.put(dbhelper.BOOKS_SHELFORDER, dShelfOrder); 
         args.put(dbhelper.BOOKS_BOOKSORDER, dBookOrder); 
         BookManager.updateBook(v.getContext().getContentResolver(), data.getItemAt(0).getText().toString(), args); 

         /** 
         * Update book being dragged to 
         */ 
         ContentValues values = new ContentValues(); 
         values.put(dbhelper.BOOKS_SHELFORDER, oShelfOrder); 
         values.put(dbhelper.BOOKS_BOOKSORDER, oBookOrder); 
         BookManager.updateBook(v.getContext().getContentResolver(), BookId, values); 

         if(v.getContext() instanceof OrderBooks){ 
          ((OrderBooks)v.getContext()).adapter.refresh(); 
          ((OrderBooks)v.getContext()).adapter.notifyDataSetChanged(); 

          PositionOfDraggedItem = -1; 
         } 
        } 
       } 
      } 
      break; 
     case DragEvent.ACTION_DRAG_ENDED: 
      if(event != null && event.getResult()) 
      { 
       v.invalidate(); 
      } 
      break; 
    } 
    return state; 
} 

}

有沒有在一段時間的工作就可以了,更新,以反映最新的變化。

+0

smoothScrollToPosition每次都會啓動一個滾動條動畫,我認爲最好是每隔1秒發佈一次smoothScrollToPosition(數量,線性),但這種方法不公開或不受保護... – molikto 2012-11-11 03:37:19

+0

This解決方案完美滾動,但是,列表中的視圖的DragListeners在滾動前不可見並且在拖動時不起作用。當我拖動一個對象到列表視圖的較低區域時,它會向下滾動,但通過滾動可見的視圖上的DragListener不會獲得任何事件。當我無需滾動即可與他們聯繫時,他們照常工作。 你們有沒有想出解決方案? – 2013-04-13 17:58:57

0

我實施了這個適合我的解決方案。以下方法在我的Activity中,當dragEvent爲ACTION_DRAG_ENTERED時,它在我的dragEventListener中調用。一些屬性,我宣佈:

//first visible item (getFirstVisiblePosition() does not work for me) 
int firstVisible; 
//number of scrolls 
int nbrScroll; 
//my listview to scroll 
ListView mListView; 
//the adapter of my listview 
SimpleAdapter mAdapter; 

...

public void scrollDrag(int position) { 
      //this is the position of the item in my listview 
      //to scroll down 
      //test if the item entered is the last visible 
    if (position == mListView.getLastVisiblePosition() 
      && id < mListView.getCount()) { 
     mAdapter.notifyDataSetChanged(); 
     mRightDrawerList.post(new Runnable() { 
      @Override 
      public void run() { 
       //scroll down 
       mListView.smoothScrollToPosition(mListView 
         .getLastVisiblePosition() + 1); 
       firstVisible++; 
      } 
     }); 
      //to scroll up 
      //test if the item entered is the first visible 
    } else if (position == firstVisible && position !=0) { 
     mAdapter.notifyDataSetChanged(); 
     mListView.post(new Runnable() { 
      @Override 
      public void run() { 
       //scroll up 
       mListView.smoothScrollToPosition(firstVisible-1); 
       firstVisible --; 
      } 
     }); 
    } 
} 

希望它會幫助別人。

-1

他們我在rickey的代碼中做了一些改動,它對我很有用。

if (PositionOfItemDraggedOver == PositionOfLastVisibleView) 
    order_item_list_lv.smoothScrollToPosition(PositionOfLastVisibleView + 1); 

if (PositionOfItemDraggedOver == PositionOfFirstVisibleView) 
    order_item_list_lv.smoothScrollToPosition(PositionOfFirstVisibleView - 1);