11

साथ प्रयोग किया जाता है ItemTouchHelper की ड्रॉप कार्रवाई को पकड़ने के लिए।एंड्रॉयड - कैसे जो मैं के साथ <strong>की <strong>ItemTouchHelper</strong> RecyclerView</strong> एक समस्या है RecyclerView

मैं एक गेम बना रहा हूं। खेल बोर्ड वास्तव में एक RecyclerView है। रीसाइक्लर व्यू में कुछ स्पैन गिनती के साथ ग्रिडलेआउट प्रबंधक है। मैं को & रीसाइक्लिंगव्यू आइटम को ड्रैग करना चाहता हूं। कोई भी आइटम सभी दिशाओं (ऊपर, नीचे, बाएं, दाएं) पर खींच सकता है।

private void initializeLayout() { 
    recyclerView.setHasFixedSize(true); 
    recyclerView.setLayoutFrozen(true); 
    recyclerView.setNestedScrollingEnabled(false); 

    // set layout manager 
    GridLayoutManager layoutManager = new GridLayoutManager(getContext(), BOARD_SIZE, 
     LinearLayoutManager.VERTICAL, true); 
    recyclerView.setLayoutManager(layoutManager); 

    // Extend the Callback class 
    ItemTouchHelper.Callback itemTouchCallback = new ItemTouchHelper.Callback() { 

    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
     Log.w(TAG, "onMove"); 
     return false; 
    } 

    @Override 
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 
     // Application does not include swipe feature. 
    } 

    @Override 
    public void onMoved(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, 
         int fromPos, RecyclerView.ViewHolder target, int toPos, int x, int y) { 
     Log.d(TAG, "onMoved"); 
     // this is calling every time, but I need only when user dropped item, not after every onMove function. 
    } 

    @Override 
    public boolean isItemViewSwipeEnabled() { 
     return false; 
    } 

    @Override 
    public boolean isLongPressDragEnabled() { 
     return true; 
    } 

    @Override 
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 
     int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END; 
     int swipeFlags = 0; 
     return makeMovementFlags(dragFlags, swipeFlags); 
    } 
    }; 

    ItemTouchHelper touchHelper = new ItemTouchHelper(itemTouchCallback); 
    touchHelper.attachToRecyclerView(recyclerView); 
} 

हां, तो क्यों ItemTouchHelper के onMoved समारोह काम करता है जब मैं अभी भी RecyclerView पर आइटम खींचकर? इसे कैसे प्राप्त किया जा सकता है ?

उत्तर

1

आप एडाप्टर में OnMove श्रोता का एहसास होना चाहिए:

Collections.swap(youCoolList, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition);

इस आदमी https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.blviq6jxp

विशेष ग्रिड उदाहरण https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd#.xb74uu7ke

35

कर "खींचें & बूंद से एक समय पर की तरह ", onMove() को एक से अधिक बार बुलाया जाएगा, लेकिन clearView() cal होगा एक बार नेतृत्व किया। तो आप ड्रैग खत्म होने के संकेत के लिए इसका उपयोग कर सकते हैं (ड्रॉप हुआ था)। और एक पूर्ण "ड्रैग & ड्रॉप" में वास्तव में स्थिति का पता लगाने के लिए ड्रैगफ्रॉम और ड्रैग करने के लिए दो चर का उपयोग करें।

private ItemTouchHelper.Callback dragCallback = new ItemTouchHelper.Callback() { 

    int dragFrom = -1; 
    int dragTo = -1; 

    @Override 
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 
     return makeMovementFlags(ItemTouchHelper.UP|ItemTouchHelper.DOWN|ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT, 
       0); 
    } 

    @Override 
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 

     int fromPosition = viewHolder.getAdapterPosition(); 
     int toPosition = target.getAdapterPosition(); 


     if(dragFrom == -1) { 
      dragFrom = fromPosition; 
     } 
     dragTo = toPosition; 

     adapter.onItemMove(fromPosition, toPosition); 

     return true; 
    } 

    private void reallyMoved(int from, int to) { 
     // I guessed this was what you want... 
    } 

    @Override 
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 

    } 

    @Override 
    public boolean isLongPressDragEnabled() { 
     return true; 
    } 

    @Override 
    public boolean isItemViewSwipeEnabled() { 
     return false; 
    } 

    @Override 
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 
     super.clearView(recyclerView, viewHolder); 

     if(dragFrom != -1 && dragTo != -1 && dragFrom != dragTo) { 
      reallyMoved(dragFrom, dragTo); 
     } 

     dragFrom = dragTo = -1; 
    } 

}; 

adapter.onItemMove (fromPosition, toPosition) था नीचे की तरह:
- ACTION_STATE_IDLE:

list.add(toPosition, list.remove(fromPosition)); notifyItemMoved(fromPosition, toPosition);

+0

मैं इस देख रहा था: =) की उम्मीद – Beyaz

+0

मैं यह पता लगाने की पता है कि कैसे ड्रॉप पूरा कर लिया है की कोशिश कर रहा हूँ। ClearView() का आपका स्पष्टीकरण सही है। कार्यान्वयन को दिखाने के लिए भी धन्यवाद। – andre719mv

+0

के रूप में काम करता है – seekingStillness

2

onSelectedChanged(RecyclerView.ViewHolder, int) कॉलबैक वर्तमान actionState बारे में जानकारी प्रदान
- ACTION_STATE_DRAG
- ACTION_STATE_SWIPE

तो आप ट्रैक रख सकते हैं कि ऑर्डर बदल गया है, और जब राज्य ACTION_STATE_IDLE में बदल जाता है, तो आप जो कर सकते हैं वह कर सकते हैं!

उदाहरण:

private final class MyCallback extends ItemTouchHelper.Callback { 
    private boolean mOrderChanged; 

    @Override 
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
     // Check if positions of viewHolders correspond to underlying model, and if not, flip the items in the model and set the mOrderChanged flag 
     mOrderChanged = true; 
    } 

    @Override 
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { 
    super.onSelectedChanged(viewHolder, actionState); 

    if (actionState == ItemTouchHelper.ACTION_STATE_IDLE && mOrderChanged) { 
     doSomething(); 
     mOrderChanged = false; 
    } 
} 
+0

यह मेरा सहज जवाब भी था, लेकिन स्पष्ट रूप से यह अपेक्षित काम नहीं करता है ... –

+0

यह मेरे लिए काम करता था। तुम्हारे लिए क्या काम नहीं कर रहा है? –

+0

मैंने प्रत्येक बार 'चयनित चयन किया गया' नामक पिछली स्थिति को ट्रैक करके सफलतापूर्वक इस तरह की एक विधि का उपयोग किया - यदि यह 'ACTION_STATE_DRAG' होने का उपयोग किया गया था और अब' ACTION_STATE_IDLE' है तो 'कुछ() ' – andygeers

संबंधित मुद्दे