DragSelectRecyclerView
DragSelectRecyclerView copied to clipboard
TouchListener that can be attached to any RecyclerView and handles multi selection for you
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)
- add jitpack to your project's
build.gradle
:
repositories {
maven { url "https://jitpack.io" }
}
- add the compile statement to your module's
build.gradle
:
dependencies {
compile 'com.github.MFlisar:DragSelectRecyclerView:0.3'
}
Usage - General
- 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;
- attach it to the
RecyclerView
recyclerView.addOnItemTouchListener(mDragSelectTouchListener);
- 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 backonDragSelectionListener = 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 theDragSelectTouchListener.OnDragSelectListener
which will notify you about the start and end of the drag selection as wellnDragSelectionListener = 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