如何在RecyclerView上启用和禁用拖放功能。

18

我有一个可编辑模式下允许拖放的RecyclerView。一旦用户退出编辑模式,我需要禁用拖放功能。

我已经尝试更改ItemTouchCallback中的移动标志和isLongPressDragEnabled,但无济于事。长按仍然会开始拖动事件。

我的当前解决方案是分离和重新加载片段,然后在再次进入编辑模式时添加回调,但我希望有些更简洁的解决方案我可能错过了。

回调:

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();
    }
}
}

适配器:

public interface ItemTouchHelperAdapter {

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

片段:

@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();
}

谢谢。


1
请提供您的代码 - Harlan
3个回答

22

在你的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;
}

正是我所需要的。谢谢! - CodeMylife
1
这个能针对特定项目禁用吗? - Lutaaya Huzaifah Idris
这就是解决方案!谢谢! - Vitaly

12

这是我的做法:

if(mode == MODE_CREATE){
  touchHelper.attachToRecyclerView(recyclerView);
}else if(mode == MODE_EDIT){
  touchHelper.attachToRecyclerView(null);
}

1
XxGoliathusxX,非常感谢,这非常有帮助。 - Daiwik Dan
如何在始终启用滑动的情况下禁用拖动? - Michael Abyzov
无法工作的解决方案。尝试拖动时出现了NullPointerException异常。 - Vitaly

1

根据@chicken的回答,这是为了禁用除YourAdapter.ViewHolder之外的每个其他viewHolder的拖动。 希望能对某些人有所帮助

 override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
                return if (viewHolder is YourAdapter.ViewHolder) {
                        super.getMovementFlags(recyclerView, viewHolder)
                    } else {
                        0
                    }
                }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接