Отключить прокрутку для позиции в RecyclerView с помощью ItemTouchHelper.SimpleCallback

Я использую recyclerview 22.2.0 и вспомогательный класс ItemTouchHelper.SimpleCallback, чтобы включить опцию swipe-to- reject в моем списке. Но поскольку у меня есть тип заголовка, мне нужно отключить поведение салфетки для первой позиции адаптера. Поскольку RecyclerView.Adapter не имеет метода isEnabled () , я попытался отключить взаимодействие вида с помощью методов isEnabled () и isFocusable () в самом представлении ViewHolder, но не имел успеха. Я попытался настроить порог салфетки на полное значение, например 0f ot 1f в методе SimpleCallback getSwipeThreshold () , но не имеет успеха.

Некоторые фрагменты кода, которые помогут вам помочь.

Моя активность:

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

И у меня есть общий адаптер с двумя типами просмотра. В 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); } } 

Solutions Collecting From Web of "Отключить прокрутку для позиции в RecyclerView с помощью ItemTouchHelper.SimpleCallback"

Немного поиграв, мне удалось, что 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); } 

Здесь вместо dragFlags и swipeFlags Вы можете передать 0, чтобы отключить соответствующую функцию.

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

Является ли это лучше, чем другие ответы, зависит от ваших потребностей. Если у вас есть конкретные типы держателей, которые не должны быть пробиты, принятый ответ будет работать хорошо. Если способность прокрутки зависит от данных для элемента, то вы можете использовать position для получения данных от адаптера для прокручиваемого элемента и соответственно отключить его. И, наконец, если вы действительно хотите отключить работу на основе позиции, этот ответ будет работать хорошо.

Есть несколько способов сделать это, но если у вас есть только один ViewHolder, но более одного макета, вы можете воспользоваться этим подходом.

Переопределите getItemViewType и дайте ему некоторую логику определения типа представления на основе позиции или типа данных в объекте (у меня есть функция getType в моем объекте)

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

Верните правильный макет в onCreateView на основе ViewType (убедитесь, что вы передаете тип вида классу 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); } } 

Получать представления контента различных макетов на основе типа открытого типа public static AppListItemHolder расширяет 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); } }