使用ItemTouchHelper.SimpleCallback禁用Swipe在RecyclerView中的位置

我正在使用recyclerview 22.2.0和辅助类ItemTouchHelper.SimpleCallback来启用滑动到解除选项到我的列表。 但是,因为我有一个types的标题,我需要禁用适配器的第一个位置的滑动行为。 由于RecyclerView.Adapter没有一个isEnabled()方法,我尝试通过ViewHolder创build本身中的方法isEnabled()isFocusable()禁用视图交互,但没有成功。 我尝试将滑动阈值调整为完全值,如SimpleCallback方法getSwipeThreshold()中的0f ot 1f ,但是也没有成功。

我的代码的一些片段,以帮助你来帮助我。

我的活动:

@Override protected void onCreate(Bundle bundle) { //... initialization ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) { @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { return false; } @Override public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) { if (viewHolder instanceof CartAdapter.MyViewHolder) return 1f; return super.getSwipeThreshold(viewHolder); } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) { } }; ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback); itemTouchHelper.attachToRecyclerView(recyclerView); } 

而且我有两种视图types的通用适配器。 在我想禁用滑动的ViewHolder中,我做了:

 public static class MyViewHolder extends RecyclerView.ViewHolder { public ViewGroup mContainer; public MyViewHolder(View v) { super(v); v.setFocusable(false); v.setEnabled(false); mContainer = (ViewGroup) v.findViewById(R.id.container); } } 

玩了一下之后,我pipe理了SimpleCallback有一个名为getSwipeDirs()的方法。 因为我有一个不滑动的位置的特定的ViewHolder,我可以使用instanceof来避免滑动。 如果这不是你的情况,你可以使用适配器中ViewHolder的位置来执行这个控制。

 @Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { if (viewHolder instanceof CartAdapter.MyViewHolder) return 0; return super.getSwipeDirs(recyclerView, viewHolder); } 

如果有人正在使用ItemTouchHelper.Callback 。 然后,您可以删除getMovementFlags(..)函数中的任何相关标志。

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

在这里,而不是dragFlagsswipeFlags你可以通过0来禁用相应的function。

ItemTouchHelper.START表示从左到右语言环境(LTR应用程序支持)从左到右滑动, 反之则从右到左语言环境(RTL应用程序支持)。 ItemTouchHelper.END意味着以START的相反方向滑动。

所以你可以根据你的要求删除任何标志。

这是一个简单的方法,这样做只取决于被滑动的项目的位置:

 @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder holder) { int position = holder.getAdapterPosition(); int dragFlags = 0; // whatever your dragFlags need to be int swipeFlags = position == 0 ? 0 : ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags); } 

如果您使用SimpleCallback,这也应该工作:

 @Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder holder) { int position = holder.getAdapterPosition(); return position == 0 ? 0 : super.getSwipeDirs(recyclerView, viewHolder); } 

这是否比其他答案更好取决于你的需求。 如果您有特定的持有人types,不需要刷卡,那么接受的答案就会很好。 如果刷卡能力取决于物品的数据,则可以使用position从适配器中获取正在刷卡的物品的数据并相应地禁用。 最后,如果你真的只是想停用基于位置,这个答案会很好。

有几种方法可以解决这个问题,但是如果你只有一个ViewHolder,但是你可以采用多个布局。

重写getItemViewType,并给它一些逻辑,以确定基于对象中的数据的位置或types的视图types(我在我的对象中有一个getType函数)

 @Override public int getItemViewType(int position) { return data.get(position).getType; } 

在基于ViewType的onCreateView中返回适当的布局(确保将视图types传递给ViewHolder类。

 @Override public AppListItemHolder onCreateViewHolder(ViewGroup parent, int viewType) { mContext = parent.getContext(); if (viewType == 0){ return new AppListItemHolder(LayoutInflater.from(mContext).inflate(R.layout.layout, parent, false), viewType); else return new AppListItemHolder(LayoutInflater.from(mContext).inflate(R.layout.header, parent, false), viewType); } } 

基于视图types获取不同布局的内容视图public static class AppListItemHolder extends RecyclerView.ViewHolder {

  public AppListItemHolder (View v, int viewType) { super(v); if (viewType == 0) ... get your views contents else ... get other views contents } } } 

然后在您的ItemTouchHelper基于ViewType的更改操作。 对于我来说,这将禁用一个RecyclerView节标题的滑动

 @Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { if (viewHolder.getItemViewType() == 1) return 0; return super.getSwipeDirs(recyclerView, viewHolder); } }