Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable and disable Drag and Drop on a recyclerview

I've got a recyclerview that allows for drag and drop of items when in edit mode. Once the user exits edit-mode I need to disable the drag and drop functionality.

I have tried changing things in the ItemTouchCallback including the movement flags and isLongPressDragEnabled to no avail. Long press continued to start the drag event.

My current solution is to detach and reattach the fragment, and then just add the callback when entering edit mode again, however I'm hoping there's something a bit cleaner that I'm missing.

Callback:

public class ItemTouchCallback extends ItemTouchHelper.Callback {


private final ItemTouchHelperAdapter mAdapter;

public ItemTouchCallback(ItemTouchHelperAdapter mAdapter) {
    this.mAdapter = mAdapter;
}

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

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
    mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
    return true;
}

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

}

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


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

@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
    if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
        if (viewHolder instanceof ItemTouchHelperViewHolder) {
            ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
            itemViewHolder.onItemSelected();
        }
    }
    super.onSelectedChanged(viewHolder, actionState);
}

@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    if (viewHolder instanceof ItemTouchHelperViewHolder) {
        ItemTouchHelperViewHolder itemViewHolder = (ItemTouchHelperViewHolder) viewHolder;
        itemViewHolder.onItemClear();
    }
}
}

Adapter:

public interface ItemTouchHelperAdapter {

void onItemMove(int fromPosition, int toPosition);
void onItemDismiss(int position);
}

Fragment:

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                   Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_rectangle_switches, container, false);

    ButterKnife.bind(this, rootView);

    // Note: Title set by AmbientPagerFragment

    layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
    recyclerView.setLayoutManager(layoutManager);

    adapter = new SwitchAdapter(switchList, dimmableList, ghostList, editMode, bus);
    recyclerView.setAdapter(adapter);

    displaySwitches();
    return rootView;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.icon_edit:
            editMode = true;
            changeEditMode();
            break;
        case R.id.icon_cancel:
            editMode = false;
            changeEditMode();
            break;
    }
    return super.onOptionsItemSelected(item);
}

public void changeEditMode() {
    bus.post(new EditModeEvent(editMode));

    reattachFragment();

    displaySwitches();
    getActivity().invalidateOptionsMenu();
}

private void displaySwitches() {

    if (editMode) {
        callback = new ItemTouchCallback((ItemTouchHelperAdapter) adapter);
        mTouchHelper = new ItemTouchHelper(callback);
        mTouchHelper.attachToRecyclerView(recyclerView);
        }
    }

private void reattachFragment(){
    ft = getFragmentManager().beginTransaction();
    ft.detach(this).attach(this).commit();
}

Thanks.

like image 970
JordynM Avatar asked Jul 12 '16 23:07

JordynM


2 Answers

In your ItemTouchCallback

boolean mDraggable = false;

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    int dragFlags = mDraggable ? UP | DOWN | START | END : 0;
    return makeMovementFlags(dragFlags, 0);
}
public void setDraggable(boolean value) {
    mDraggable = value;
}
like image 71
chicken Avatar answered Oct 12 '22 20:10

chicken


Thats the way I do it:

if(mode == MODE_CREATE){
  touchHelper.attachToRecyclerView(recyclerView);
}else if(mode == MODE_EDIT){
  touchHelper.attachToRecyclerView(null);
}
like image 11
XxGoliathusxX Avatar answered Oct 12 '22 19:10

XxGoliathusxX