J'utilise recyclerview 22.2.0 et la classe d'assistance ItemTouchHelper.SimpleCallback pour activer l' option glisser pour rejeter dans ma liste. Mais comme j'ai un type d'en-tête dessus, je dois désactiver le comportement de balayage pour la première position de l'adaptateur. Comme RecyclerView.Adapter n'a pas de méthode isEnabled () , j'ai essayé de désactiver l'interaction de vue via les méthodes isEnabled () et isFocusable () dans la création de ViewHolder elle-même, mais sans succès. J'ai essayé d'ajuster le seuil de balayage à une valeur complète, comme 0f ot 1f dans la méthode getSwipeThreshold () de SimpleCallback , mais sans succès aussi.
Quelques fragments de mon code pour vous aider à m'aider.
Mon activité:
@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);
}
Et j'ai un adaptateur commun avec deux types de vue. Dans le ViewHolder que je souhaite désactiver le balayage, j'ai fait:
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);
}
}
la source
SimpleCallback
developer.android.com/intl/pt-br/reference/android/support/v7/…return position == 0 ? ItemTouchHelper.LEFT : super.getSwipeDirs(recyclerView, viewHolder);
- celui-ci, c'est-à-dire ne permettre que les balayages vers la gauche.Si quelqu'un utilise ItemTouchHelper.Callback . Ensuite, vous pouvez supprimer tous les indicateurs associés dans la fonction 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); }
Ici au lieu de dragFlags et swipeFlags Vous pouvez passer 0 pour désactiver la fonction correspondante.
ItemTouchHelper.START signifie glisser de gauche à droite en cas de paramètres régionaux de gauche à droite (prise en charge des applications LTR), mais l'inverse dans les paramètres régionaux de droite à gauche (prise en charge des applications RTL). ItemTouchHelper.END signifie glisser dans la direction opposée de
START
.afin que vous puissiez supprimer n'importe quel drapeau selon vos besoins.
la source
ItemTouchHelper.Callback
directement.Voici un moyen simple de le faire qui ne dépend que de la position de l'élément balayé:
@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; }
Cela devrait également fonctionner si vous utilisez
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); }
Si vous souhaitez désactiver le balayage en fonction des données de l'élément, utilisez la
position
valeur pour obtenir des données de l'adaptateur pour l'élément en cours de balayage et désactivez-le en conséquence.Si vous avez déjà des types de détenteurs spécifiques qui ne doivent pas glisser, la réponse acceptée fonctionnera. Cependant, la création de types de détenteurs comme proxy pour la position est un kludge et doit être évitée.
la source
Il y a plusieurs façons de procéder, mais si vous n'avez qu'un seul ViewHolder, mais plusieurs mises en page, vous pouvez adopter cette approche.
Remplacez le getItemViewType et donnez-lui une certaine logique pour déterminer le type de vue en fonction de la position ou du type de données dans l'objet (j'ai une fonction getType dans mon objet)
@Override public int getItemViewType(int position) { return data.get(position).getType; }
Renvoyez la mise en page appropriée dans onCreateView en fonction de ViewType (assurez-vous de transmettre le type de vue à la 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); } }
Obtenez les vues de contenu des différentes mises en page en fonction du type de vue classe statique publique AppListItemHolder étend RecyclerView.ViewHolder {
public AppListItemHolder (View v, int viewType) { super(v); if (viewType == 0) ... get your views contents else ... get other views contents } } }
Et puis dans votre ItemTouchHelper, changez les actions basées sur ViewType. Pour moi, cela désactive le balayage d'un en-tête de section RecyclerView
@Override public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { if (viewHolder.getItemViewType() == 1) return 0; return super.getSwipeDirs(recyclerView, viewHolder); } }
la source
Tout d'abord dans la méthode recyclerView at onCreateViewHolder, définissez une balise pour chaque type de viewHolder, comme le code ci-dessous:
@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; } }
puis dans l'implémentation ItemTouchHelper.Callback, mettez à jour la méthode getMovementFlags, comme ci-dessous:
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; } }
à la fin attacher à recyclerView:
final SwipeController swipeController = new SwipeController(); ItemTouchHelper itemTouchHelper = new ItemTouchHelper(swipeController); itemTouchHelper.attachToRecyclerView(recyclerView);
la source
En plus de la réponse @Rafael Toledo, si vous souhaitez supprimer le geste de balayage spécifique comme le balayage GAUCHE ou le balayage DROIT en fonction de la position ou du type de données dans l'objet dans Adapter, vous pouvez faire comme ceci.
@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; }
Ici, dans mon cas, dans mon Recyclerview, je charge les conversations de chat et il y a des gestes de balayage DROIT (pour ARCHIVE) et GAUCHE (pour EXIT) sur chaque élément. Mais au cas où la conversation n'est pas active, je dois désactiver le balayage DROIT pour l'élément spécifique dans la vue Recycleur.
Je vérifie donc le
activeChat
et en conséquence et j'ai désactivé le balayage DROIT.la source
Il peut être désactivé en utilisant
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)
la source