DragSelectRecyclerView

Additional

Language
Java
Version
0.3 (Mar 6, 2017)
Created
Jan 25, 2017
Updated
Mar 19, 2021 (Retired)
Owner
MFlisar
Contributor
MFlisar
1
Activity
Badge
Generate
Download
Source code

DragSelectRecyclerView

What is it / What does it do?

It's a simple one class TouchListener that can be attached to any RecyclerView and handles multi selection in google photos style via long pressing on an item and moving the finger up/down to select more items (it even scrolls if you reach the edges of the RecyclerView)

Gradle (via JitPack.io)

  1. add jitpack to your project's build.gradle:
repositories {
 maven { url "https://jitpack.io" }
}
  1. add the compile statement to your module's build.gradle:
dependencies {
 compile 'com.github.MFlisar:DragSelectRecyclerView:0.3'
}

Usage - General

  1. Create the a touch listener like following
mDragSelectTouchListener = new DragSelectTouchListener()
 // check region OnDragSelectListener for more infos
 .withSelectListener(onDragSelectionListener)
 // following is all optional
 .withMaxScrollDistance(distance)    // default: 16;  defines the speed of the auto scrolling
 .withTopOffset(toolbarHeight)       // default: 0;   set an offset for the touch region on top of the RecyclerView
 .withBottomOffset(toolbarHeight)    // default: 0;   set an offset for the touch region on bottom of the RecyclerView
 .withScrollAboveTopRegion(enabled)  // default: true;  enable auto scrolling, even if the finger is moved above the top region
 .withScrollBelowTopRegion(enabled)  // default: true;  enable auto scrolling, even if the finger is moved below the top region
 .withDebug(enabled);                // default: false;
  1. attach it to the RecyclerView
recyclerView.addOnItemTouchListener(mDragSelectTouchListener);
  1. on item long press, inform the listener so that it can start doing it's magic
// if one item is long pressed, we start the drag selection like following:
// we just call this function and pass in the position of the first selected item
mDragSelectTouchListener.startDragSelection(position);

Usage - OnDragSelectListener

You have 3 options:

  • use a simple DragSelectTouchListener.OnDragSelectListener => you get notified over which items the user dragged or dragged back

       onDragSelectionListener = new DragSelectTouchListener.OnDragSelectListener() {
      @Override
      public void onSelectChange(int start, int end, boolean isSelected) {
       // update your selection
       // range is inclusive start/end positions
      }
       }
  • use a DragSelectTouchListener.OnAdvancedDragSelectListener => this is an extended version of the DragSelectTouchListener.OnDragSelectListener which will notify you about the start and end of the drag selection as well

     onDragSelectionListener = new DragSelectTouchListener.OnAdvancedDragSelectListener()
     {
      @Override
      public void onSelectChange(int start, int end, boolean isSelected) {
       // update your selection
       // range is inclusive start/end positions
      }
    
      @Override
      public void onSelectionStarted(int start) {
       // drag selection was started at index start
      }
    
      @Override
      public void onSelectionFinished(int end) {
       // drag selection was finished at index start
      }
     };
  • Preferred option: use the DragSelectionProcessor, it implements the above mentioned interface and can be set up with 4 modes:

    • Simple: simply selects each item you go by and unselects on move back
    • ToggleAndUndo: toggles each items original state, reverts to the original state on move back
    • FirstItemDependent: toggles the first item and applies the same state to each item you go by and applies inverted state on move back
    • FirstItemDependentToggleAndUndo: toggles the item and applies the same state to each item you go by and reverts to the original state on move back

The DragSelectionProcessor will take care to transform each event to the correct select/deselect event that must be handled by you afterwards. Therefore you must provide a ISelectionHandler in it's constructor. Just implement it's 3 simple functions and you're done.

onDragSelectionListener = new DragSelectionProcessor(new DragSelectionProcessor.ISelectionHandler() {
 @Override
 public Set<Integer> getSelection() {
  // return a set of all currently selected indizes
  return selection;
 }

 @Override
 public boolean isSelected(int index) {
  // return the current selection state of the index
  return selected;
 }

 @Override
 public void updateSelection(int start, int end, boolean isSelected, boolean calledFromOnStart) {
  // update your selection
  // range is inclusive start/end positions
  // and the processor has already converted all events according to it'smode
 }
})
 // pass in one of the 4 modes, simple mode is selected by default otherwise
 .withMode(DragSelectionProcessor.Mode.FirstItemDependentToggleAndUndo);

A demo can be found here: MainActivity.java

TODO

  • support horizontal RecyclerViews... should be quite simple, but is not yet implemented

Credits

This library is heavily inspired and based on https://github.com/weidongjian/AndroidDragSelect-SimulateGooglePhoto