Androïde RecyclerView ItemTouchHelper Swipe et restore view holder
y a-t-il un moyen de revenir sur une action de balayage et de restaurer le support de vue à sa position initiale après le balayage est terminé et onSwiped
est appelé le ItemTouchHelper.Callback
exemple? J'ai eu l' RecyclerView
, ItemTouchHelper
et ItemTouchHelper.Callback
instances pour fonctionner parfaitement ensemble, j'ai juste besoin de revenir en arrière l'action de balayage et dans certains cas, enlever l'objet piqué.
6 réponses
après quelques recherches aléatoires, j'ai trouvé une solution. Appeler notifyItemChanged
sur votre adaptateur. Cela fera la vue swiped out animer de nouveau dans sa position originale.
Google ItemTouchHelper
la mise en oeuvre suppose que tous les l'article copié sera éventuellement retiré du point de vue du recycleur, alors que cela pourrait ne pas être le cas dans certaines applications.
RecoverAnimation
est une classe imbriquée dans ItemTouchHelper
qui gère l'animation tactile des objets glissés/traînés. Bien que le nom implique qu'il ne récupère la position des objets, c'est en fait la seule classe qui est utilisée pour récupérer (annuler glisser / glisser) et remplacer (déplacer sur glisser ou remplacer sur glisser) articles. Étrange de nommage.
Il y a une propriété booléenne nommée mIsPendingCleanup
RecoverAnimation
ItemTouchHelper
sert à déterminer si l'article est en attente de suppression. Donc ItemTouchHelper
, après avoir fixé un RecoverAnimation
à l'item, définit cette propriété après un swipe réussi, et l'animation ne sera pas retirée de la liste des animations de récupération aussi longtemps que cette propriété est définie. Le problème est que, mIsPendingCleanup
sera toujours ensemble pour un glissée élément, provoquant l' RecoverAnimation
pour que l'article ne soit jamais retiré de la liste des animations. Donc, même si vous récupérez l'élément de position après une successul balayage, il sera renvoyé à l'glissée position dès que vous le touchez - parce que le RecoverAnimation sera la cause de l'animation de début de la dernière glissée position.
la Solution à cela est malheureusement de copier le ItemTouchHelper
classe le code source dans le même paquet que dans la bibliothèque de soutien, et supprimer le mIsPendingCleanup
propriété de l' RecoverAnimation
classe. Je ne suis pas sûr que cela soit acceptable par Google, et je n'ai pas encore posté la mise à jour de Play Store pour voir si elle causera un rejet, mais vous pouvez trouver le code source de classe de la bibliothèque de soutien v22.2.1 avec le repère mentionné ci-dessus à https://gist.github.com/kukabi/f46e1c0503d2806acbe2.
sale solution de contournement solution pour ce problème est de re-attacher L'ItemTouchHelper en appelant ItemTouchHelper::attachToRecyclerView(RecyclerView)
deux fois, puis appelle la méthode ItemTouchHelper::destroyCallbacks()
. destroyCallbacks()
supprime la décoration de l'article et tous les écouteurs, mais efface également toutes les imaginations de récupération.
Notez que nous devons appeler itemTouchHelper.attachToRecyclerView(null)
premier truc ItemTouchHelper
en pensant que le deuxième appel à itemTouchHelper.attachToRecyclerView(recyclerView)
est un nouveau recycleur de vue.
pour plus de détails, consultez le code source de ItemTouchHelper
ici.
Exemple de solution:
RecyclerView recyclerView = findViewById(R.id.recycler_view);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
...
// Workaround to reset swiped out views
itemTouchHelper.attachToRecyclerView(null);
itemTouchHelper.attachToRecyclerView(recyclerView);
le Considérer comme un sale solution de contournement, car cette méthode utilise en interne, sans-papiers, la mise en œuvre détail de ItemTouchHelper
.
mise à Jour:
documentationItemTouchHelper::attachToRecyclerView(RecyclerView)
:
si le TouchHelper est déjà attaché à un RecyclerView, il se détachera d'abord du précédent. Vous pouvez appeler cette méthode avec null pour le détacher de la RecyclerView actuelle.
et dans la documentation des paramètres:
L'instance RecyclerView à laquelle vous voulez ajouter cette helper ou null si vous voulez supprimer ItemTouchHelper de la RecyclerView courante.
donc au moins il est partiellement documenté.
vous devriez annuler onSwiped
méthode ItemTouchHelper.Callback
et rafraîchir ce point particulier.
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder,
int direction) {
adapter.notifyItemChanged(viewHolder.getAdapterPosition());
}
Call notifyDataSetChanged sur votre adaptateur pour rendre le travail de retour de swipe cohérent
si vous voulez voir un joli tutoriel, à propos des animations Swipe & Drap de RecyclerView, vous pouvez regarder cette vidéo, je l'ai trouvée assez utile. https://www.youtube.com/watch?v=grRAvv-uk1c&t=1228s