Estou usando o recyclerview 22.2.0 e a classe auxiliar ItemTouchHelper.SimpleCallback para habilitar a opção deslizar para dispensar em minha lista. Mas como tenho um tipo de cabeçalho, preciso desabilitar o comportamento de deslizar para a primeira posição do adaptador. Como RecyclerView.Adapter não possui o método isEnabled () , tentei desabilitar a interação da view através dos métodos isEnabled () e isFocusable () na própria criação do ViewHolder, mas não tive sucesso. Tentei ajustar o limite de furto para um valor total, como 0f ot 1f no método getSwipeThreshold () do SimpleCallback , mas também não tive sucesso.
Alguns fragmentos do meu código para ajudá-lo a me ajudar.
Minha atividade:
@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);
}
E eu tenho um adaptador comum com dois tipos de visualização. No ViewHolder que desejo desabilitar o deslizamento, fiz:
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);
}
}
fonte
SimpleCallback
developer.android.com/intl/pt-br/reference/android/support/v7/…return position == 0 ? ItemTouchHelper.LEFT : super.getSwipeDirs(recyclerView, viewHolder);
- este, isto é, permite apenas deslizar para a esquerda.Se alguém estiver usando ItemTouchHelper.Callback . Em seguida, você pode remover quaisquer sinalizadores relacionados na função 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); }
Aqui, em vez de dragFlags e swipeFlags, você pode passar 0 para desativar o recurso correspondente.
ItemTouchHelper.START significa deslizar da esquerda para a direita no caso de localidade da esquerda para a direita (suporte de aplicativo LTR), mas o contrário em localidade direita para esquerda (suporte de aplicativo RTL). ItemTouchHelper.END significa deslizar na direção oposta de
START
.então você pode remover qualquer sinalizador de acordo com seus requisitos.
fonte
ItemTouchHelper.Callback
diretamente.Esta é uma maneira simples de fazer isso que depende apenas da posição do item que está sendo deslizado:
@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; }
Isso também deve funcionar se você estiver usando
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); }
Se você deseja desabilitar a passagem condicional aos dados no item, use o
position
valor para obter dados do adaptador para o item que está sendo deslizado e desabilite de acordo.Se você já tem tipos de suporte específicos que não precisam ser deslizados, a resposta aceita funcionará. No entanto, criar tipos de titular como um proxy para a posição é uma confusão e deve ser evitado.
fonte
Existem algumas maneiras de fazer isso, mas se você tiver apenas um ViewHolder, mas mais de um layout, você pode usar essa abordagem.
Substitua getItemViewType e dê a ele alguma lógica para determinar o tipo de visualização com base na posição ou tipo de dados no objeto (eu tenho uma função getType em meu objeto)
@Override public int getItemViewType(int position) { return data.get(position).getType; }
Retorne o layout adequado em onCreateView com base em ViewType (certifique-se de passar o tipo de visualização para a classe 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); } }
Obtenha as visualizações de conteúdo dos diferentes layouts com base no tipo de visualização 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 } } }
E então, em seu ItemTouchHelper, altere as ações com base em ViewType. Para mim, isso desativa a passagem de um cabeçalho de seção RecyclerView
@Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { if (viewHolder.getItemViewType() == 1) return 0; return super.getSwipeDirs(recyclerView, viewHolder); } }
fonte
Primeiro, em recyclerView no método onCreateViewHolder, defina a tag para cada tipo de viewHolder, como o código abaixo:
@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; } }
em seguida, na implementação ItemTouchHelper.Callback, atualize o método getMovementFlags, como abaixo:
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; } }
no final, anexe a recyclerView:
final SwipeController swipeController = new SwipeController(); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(swipeController); itemTouchHelper.attachToRecyclerView(recyclerView);
fonte
Além da resposta do @Rafael Toledo, se você deseja remover o gesto específico de deslizar como deslizar para a ESQUERDA ou para a DIREITA com base na posição ou tipo de dados no objeto no Adaptador, você pode fazer assim.
@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; }
Aqui no meu caso, no meu Recyclerview estou carregando as conversas do chat e tem gestos de deslizar RIGHT (para ARCHIVE) e LEFT (para SAIR) em cada item. Mas, caso a conversa não esteja ativa, preciso desabilitar o deslizar para a DIREITA para o item específico na visualização do Reciclador.
Portanto, estou verificando o
activeChat
e, portanto, desativei o deslizar para a DIREITA.fonte
Pode ser desativado usando
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)
fonte