如何在回收站视图上启用和禁用拖放
Posted
技术标签:
【中文标题】如何在回收站视图上启用和禁用拖放【英文标题】:How to enable and disable Drag and Drop on a recyclerview 【发布时间】:2016-11-15 08:57:14 【问题描述】:我有一个回收视图,允许在编辑模式下拖放项目。一旦用户退出编辑模式,我需要禁用拖放功能。
我尝试更改 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】:在你的 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;
【讨论】:
正是我需要的。谢谢! 这可以禁用特定项目吗? 这就是解决方案!谢谢!【参考方案2】:我就是这样做的:
if(mode == MODE_CREATE)
touchHelper.attachToRecyclerView(recyclerView);
else if(mode == MODE_EDIT)
touchHelper.attachToRecyclerView(null);
【讨论】:
XxGoliathusxX 非常感谢您的帮助。 如何在始终启用滑动的情况下禁用拖动? 不工作的解决方案。尝试拖动时发生 NullPointerException以上是关于如何在回收站视图上启用和禁用拖放的主要内容,如果未能解决你的问题,请参考以下文章