Я использую recyclerview 22.2.0 и вспомогательный класс ItemTouchHelper.SimpleCallback, чтобы включить в свой список опцию « смахнуть для увольнения» . Но поскольку у меня есть тип заголовка, мне нужно отключить поведение смахивания для первой позиции адаптера. Поскольку 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);
}
}
источник
SimpleCallback
developer.android.com/intl/pt-br/reference/android/support/v7/…return position == 0 ? ItemTouchHelper.LEFT : 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
.так что вы можете удалить любой флаг в соответствии с вашими требованиями.
источник
ItemTouchHelper.Callback
напрямую.Вот простой способ сделать это, который зависит только от положения перемещаемого элемента:
@Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder holder) { int position = holder.getAdapterPosition(); int dragFlags = 0; // whatever your dragFlags need to be int swipeFlags = createSwipeFlags(position) return makeMovementFlags(dragFlags, swipeFlags); } private int createSwipeFlags(int position) { return position == 0 ? 0 : ItemTouchHelper.START | ItemTouchHelper.END; }
Это также должно работать, если вы используете
SimpleCallback
:@Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder holder) { int position = holder.getAdapterPosition(); return createSwipeFlags(position); } private int createSwipeFlags(int position) { 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); } }
Получить представления содержимого различных макетов на основе открытого статического класса типа представления 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); } }
источник
Сначала в recyclerView в методе onCreateViewHolder установите тег для каждого типа viewHolder, как показано ниже:
@Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { if(ITEM_TYPE_NORMAL == viewType) { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.deposite_card_view, viewGroup, false); ItemViewHolder holder = new ItemViewHolder(context, v); holder.itemView.setTag("normal"); return holder; } else { View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.card_header, viewGroup, false); HeaderViewHolder holder = new HeaderViewHolder(context, v); holder.itemView.setTag("header"); return holder; } }
затем в реализации ItemTouchHelper.Callback обновите метод getMovementFlags, как показано ниже:
public class SwipeController extends ItemTouchHelper.Callback { @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { if("normal".equalsIgnoreCase((String) viewHolder.itemView.getTag())) { return makeMovementFlags(0, LEFT | RIGHT); } else { return 0; } }
в конце прикрепите к recyclerView:
final SwipeController swipeController = new SwipeController(); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(swipeController); itemTouchHelper.attachToRecyclerView(recyclerView);
источник
В дополнение к ответу @Rafael Toledo, если вы хотите удалить конкретный жест смахивания, такой как Смахивание ВЛЕВО или Смахивание ВПРАВО, в зависимости от положения или типа данных в объекте в Адаптере, вы можете сделать это.
@Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int position = viewHolder.getAdapterPosition(); ConversationDataModel conversationModel = null; conversationModel = mHomeAdapter.getItems().get(position); boolean activeChat = true; if(conversationModel!=null && !conversationModel.isActive()) { activeChat = false; } return activeChat ? super.getSwipeDirs(recyclerView, viewHolder): ItemTouchHelper.RIGHT; }
Здесь, в моем случае, в моем Recyclerview я загружаю разговоры в чате, и у него есть жесты смахивания ВПРАВО (для АРХИВА) и ВЛЕВО (для ВЫХОДА) для каждого элемента. Но в случае, если разговор не активен, мне нужно отключить ВПРАВО для конкретного элемента в представлении Recycler.
Итак, я проверяю
activeChat
и, соответственно, отключил ПРАВЫЙ свайп.источник
Его можно отключить с помощью
ItemTouchHelper.ACTION_STATE_IDLE
ItemTouchHelper.SimpleCallback( ItemTouchHelper.UP or ItemTouchHelper.DOWN, //drag directions ItemTouchHelper.ACTION_STATE_IDLE //swipe directions )
val touchHelperCallback = object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN, ItemTouchHelper.ACTION_STATE_IDLE) { override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { (recyclerView.adapter as MyAdapter).onItemMove(viewHolder.adapterPosition, target.adapterPosition) return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { return } } val touchHelper = ItemTouchHelper(touchHelperCallback) touchHelper.attachToRecyclerView(recyclerViewX)
источник