Search code examples
androidandroid-recyclerviewscrollview

Auto-scroll Scrollbar While Drag item In Recyclerview


I have an issue with Auto-scroll in scroll view.

In my case, there are two Recyclerview. First Recyclerview, horizontally scrollable and second vertically. First RecyclerView only for drag and Second RecyclerView only for a drop. Both recyclerviews are inside ScrollView so, I disabled vertical scroll in second Recyclerview. I added DragListener on Second Recyclerview's item. Every item have drag listener so based on that I add/replace item while drop item.

So My main issue with scroll, so scroll not working properly while i drag item. currently i used below code for scroll while drag.

case DragEvent.ACTION_DRAG_LOCATION:
RecyclerView recyclerView = (RecyclerView) viewSource.getParent();
MyAdapter adapter = (MyAdapter) recyclerView.getAdapter();
int y = Math.round(dragEvent.getY());
Timber.d("onDrag(): " + y);
int translatedY = y - adapter.getScrollDistance();
Timber.d("onDrag(): translated : " + translatedY + "   getScrollDistance : " + adapter.getScrollDistance());
int threshold = 50;
// make a scrolling up due the y has passed the threshold
if (translatedY < threshold) {
    // make a scroll up by 30 px
     mScrollView.smoothScrollBy(0, -30);

} else
    // make a autoscrolling down due y has passed the 500 px border
    if (translatedY + threshold > 500) {
        // make a scroll down by 30 px
     mScrollView.smoothScrollBy(0, 30);
    }
break;

But above code not working properly for multiple items if recyclerview have only one item than its working fine. but when recyclerview having multiple items that time scrollview scroll above and below slitly while itemX in between two items.

Edited Question: Now, I put above code on Second Recycler view's OnDragListener. Now the problem with drag listener, so I want if user drag First Recyclerview's item below/above than second Recyclerview's drag listener needs to work else Second Recyclerview's item's drag listener needs to work.


Solution

  • I resolved this issue by returning false in Second RecyclerView's item's drag listener's ACTION_DRAG_LOCATION event. I disabled ACTION_DRAG_LOCATION event, so that event not tracked by Second RecyclerView's Item's DragListener. That time Its Parent(Second RecyclerView)'s Draglistener work. Below code, I put on Second RecyclerView's DragListener

    case DragEvent.ACTION_DRAG_LOCATION:
    RecyclerView recyclerView = (RecyclerView) viewSource.getParent();
    MyAdapter adapter = (MyAdapter) recyclerView.getAdapter();
    int y = Math.round(dragEvent.getY());
    
    int translatedY = y - adapter.getScrollDistance();
    
    int threshold = 50;
    // make a scrolling up due the y has passed the threshold
    if (translatedY < threshold) {
        // make a scroll up by 30 px
         mScrollView.smoothScrollBy(0, -30);
    
    } else
        // make a autoscrolling down due y has passed the 500 px border
        if (translatedY + threshold > 500) {
            // make a scroll down by 30 px
         mScrollView.smoothScrollBy(0, 30);
        }
    break;
    

    To disable Second RecyclerView's item's DragListener's ACTION_DRAG_LOCATION event use below code:

     @Override
        public boolean onDrag(View view, DragEvent dragEvent) {
            int action = dragEvent.getAction();
            View viewSource = (View) dragEvent.getLocalState();
            switch (action) {
                case DragEvent.ACTION_DRAG_STARTED:
                    break;
                case DragEvent.ACTION_DRAG_ENTERED:
    
                    break;
                case DragEvent.ACTION_DRAG_LOCATION:
    
                    return false;
                case DragEvent.ACTION_DRAG_EXITED:
    
                    break;
                case DragEvent.ACTION_DROP:
    
                    break;
                default:
                    break;
            }
    
            return true;
        }
    

    So whatever Event from Draglistener you need to handle you just need to return true otherwise return false.