如何在回收站视图上启用和禁用拖放

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

以上是关于如何在回收站视图上启用和禁用拖放的主要内容,如果未能解决你的问题,请参考以下文章

当我禁用/启用按钮时,视图如何重绘自身?

如何以编程方式为特定视图控制器禁用/启用睡眠模式?

如何动态启用\禁用对话框视图

如何在全日历中禁用拖放

如何在按钮单击时在一个视图控制器中正确启用和禁用约束

如何在Eclipse插件开发中禁用/启用视图工具栏菜单/操作