2011-03-25 21 views
8

हाय मैं सूची दृश्य पर ड्रैग और ड्रॉप करने की कोशिश कर रहा हूं। यह बहुत अच्छा काम करता है। लेकिन मैंने क्लिक करने और स्क्रॉल करने की क्षमता खो दी। मैं उन दोनों को कैसे बनाए रखूं? मैं सोच रहा था कि एक सामान्य प्रेस के बजाय आइटम की लंबी प्रेस पर ड्रैग और ड्रॉप होना चाहिए। यहाँ मेरी onTouch कि MyListView में स्थित है कि ListViewएंड्रॉइड स्क्रॉल जबकि ड्रैग और ड्रॉप

@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

+0

महान घटक! मेरे लिए ठीक काम करता है ... THX – kyp

+0

उपरोक्त ब्लॉग पोस्ट लिंक काम नहीं करता है लेकिन आप यहां बाकी की चीज़ों को यहां पा सकते हैं: http://codegarage.no-ip.co.uk/snippets/94 – mpemburn

2

अतिरिक्त सहायता के लिए यह question देखें। मेरे पास DragSortListView नामक एक घटक भी है जिसे मैंने लंबे समय तक परिष्कृत किया है। आप इसे यहाँ पा सकते हैं:

मैं मदद कर सकता है आप को एकीकृत देर तक दबा मेरे ऊपर रेपो के एक कांटा में खींच शुरू की।

+0

कूल लाइब्रेरी :) –

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

+0

समाधान स्क्रॉल पूरी तरह से, हालांकि, ड्रैगलिस्ट के दृश्यों को खींचने से पहले दिखाई नहीं दे रहे थे, जो ड्रैगिंग के दौरान प्रतिक्रिया नहीं करते हैं। जब मैं किसी ऑब्जेक्ट को सूचीदृश्य के निचले क्षेत्र में खींचता हूं, तो यह नीचे स्क्रॉल करता है, लेकिन स्क्रॉलिंग द्वारा दिखाई देने वाले दृश्यों पर ड्रैगलिस्टर को कोई ईवेंट नहीं मिलता है। वे सामान्य रूप से काम करते हैं जब मैं स्क्रॉल किए बिना उन तक पहुंच सकता हूं। क्या आप में से कोई भी इसके समाधान के साथ आया था? –

0

मैंने इस समाधान को लागू किया जो मेरे लिए काम करता है। निम्न गतिविधि मेरी गतिविधि में है और इसे draggleventListener में कहा जाता है जब dragEvent ACTION_DRAG_ENTERED है। कुछ गुण मैं घोषणा की:

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

वह लोग मैंने रिकी के कोड में थोड़ा बदलाव किया है और यह मेरे लिए काम है।

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

if (PositionOfItemDraggedOver == PositionOfFirstVisibleView) 
    order_item_list_lv.smoothScrollToPosition(PositionOfFirstVisibleView - 1); 
संबंधित मुद्दे