J'utilise le nouveau CoordinatorLayout avec AppBarLayout et CollapsingToolbarLayout. Sous AppBarLayout, j'ai un RecyclerView avec une liste de contenu.
J'ai vérifié que le défilement fling fonctionne sur RecyclerView lorsque je fais défiler la liste de haut en bas. Cependant, je voudrais également que AppBarLayout défile en douceur pendant l'expansion.
Lorsque vous faites défiler vers le haut pour développer CollaspingToolbarLayout, le défilement s'arrête immédiatement une fois que vous retirez votre doigt de l'écran. Si vous faites défiler vers le haut dans un mouvement rapide, parfois le CollapsingToolbarLayout se replie également. Ce comportement avec le RecyclerView semble fonctionner très différemment que lors de l'utilisation d'un NestedScrollView.
J'ai essayé de définir différentes propriétés de défilement sur la vue de recyclage, mais je n'ai pas été en mesure de comprendre cela.
Voici une vidéo montrant certains des problèmes de défilement. https://youtu.be/xMLKoJOsTAM
Voici un exemple montrant le problème avec RecyclerView (CheeseDetailActivity). https://github.com/tylerjroach/cheesesquare
Voici l'exemple original qui utilise un NestedScrollView de Chris Banes. https://github.com/chrisbanes/cheesesquare
Réponses:
La réponse de Kirill Boyarshinov était presque correcte.
Le problème principal est que le RecyclerView donne parfois une direction de lancement incorrecte, donc si vous ajoutez le code suivant à sa réponse, cela fonctionne correctement:
J'espère que ca aide.
la source
if (target instanceof SwipeRefreshLayout && velocityY < 0) { target = ((SwipeRefreshLayout) target).getChildAt(0); }
beforeif (target instanceof RecyclerView && velocityY < 0) {
Il semble que la
v23
mise à jour ne l'a pas encore corrigé.J'ai trouvé une sorte de piratage pour le réparer en le jetant. L'astuce consiste à reprendre l'événement fling si le premier enfant de ScrollingView est proche du début des données dans Adapter.
Utilisez-le dans votre mise en page comme ça:
MODIFIER : La reconsommation des événements Fling est désormais basée sur
verticalScrollOffset
au lieu de la quantité d'éléments à partir deRecyclerView
.EDIT2: Vérifiez la cible comme
ScrollingView
instance d'interface au lieu deRecyclerView
. Les deuxRecyclerView
et leNestedScrollingView
mettre en œuvre.la source
verticalScrollOffset
qui est plus générale. À présent, l'événement de lancement sera repris lors durecyclerView
défilement vers le haut.target instanceof RecyclerView
àtarget instanceof NestedScrollView
, ou plus pour le cas générique entarget instanceof ScrollingView
. J'ai mis à jour la réponse.J'ai trouvé le correctif en appliquant OnScrollingListener au recyclerView. maintenant cela fonctionne très bien. Le problème est que recyclerview a fourni une valeur de consommation incorrecte et que le comportement ne sait pas quand le recyclerview défile vers le haut.
la source
CoordinatorLayout
etViewPager
configuration merci beaucoup pour cette solution très attendue. Veuillez écrire un GIST pour le même afin que d'autres développeurs puissent également en bénéficier. Je partage également cette solution. Merci encore.Il a été corrigé depuis la conception du support 26.0.0.
la source
Il s'agit d'une version fluide de Google Support Design AppBarLayout. Si vous utilisez AppBarLayout, vous saurez qu'il a un problème avec fling.
Voir la bibliothèque ici .. https://github.com/henrytao-me/smooth-app-bar-layout
la source
C'est un bug de recyclage. Il est censé être corrigé dans la v23.1.0.
regardez https://code.google.com/p/android/issues/detail?id=177729
la source
v26.0.1
!Ceci est ma mise en page et le parchemin Il fonctionne comme il se doit.
la source
Ma solution jusqu'à présent, basée sur les réponses de Mak Sing et Manolo Garcia .
Ce n'est pas totalement parfait. Pour l'instant, je ne sais pas comment recalculer une vitesse valide pour éviter un effet étrange: la barre d'applications peut s'étendre plus rapidement que la vitesse de défilement. Mais l'état avec une barre d'applications étendue et une vue de recycleur défilée ne peut pas être atteint.
la source
Field viewFlingerField = recyclerView.getClass().getDeclaredField("mViewFlinger"); viewFlingerField.setAccessible(true); Object flinger = viewFlingerField.get(recyclerView); Field scrollerField = flinger.getClass().getDeclaredField("mScroller"); scrollerField.setAccessible(true); ScrollerCompat scroller = (ScrollerCompat) scrollerField.get(flinger); velocity = Math.signum(mVelocity) * Math.abs(scroller.getCurrVelocity());
Dans mon cas, j'obtenais le problème où le lancer
RecyclerView
ne le faisait pas défiler en douceur, ce qui le bloquait.C'était parce que, pour une raison quelconque, j'avais oublié que j'avais mis mon
RecyclerView
dans unNestedScrollView
.C'est une erreur stupide, mais il m'a fallu un certain temps pour comprendre ...
la source
J'ajoute une vue de 1dp de hauteur à l'intérieur de l'AppBarLayout et cela fonctionne beaucoup mieux. Ceci est ma mise en page.
la source
Déjà des solutions assez populaires ici, mais après avoir joué avec elles, j'ai trouvé une solution plutôt simple qui a bien fonctionné pour moi. Ma solution garantit également que le
AppBarLayout
n'est étendu que lorsque le contenu déroulant atteint le sommet, un avantage par rapport aux autres solutions ici.la source
La réponse acceptée n'a pas fonctionné pour moi parce que j'avais à l'
RecyclerView
intérieur unSwipeRefreshLayout
et unViewPager
. Il s'agit de la version améliorée qui recherche unRecyclerView
dans la hiérarchie et devrait fonctionner pour n'importe quelle mise en page:la source
Réponse: il est corrigé dans la bibliothèque de support v26
mais la v26 a un problème lors du lancement. Parfois, AppBar rebondit à nouveau même si le fling n'est pas trop difficile.
Comment supprimer l'effet de rebond sur la barre d'applications?
Si vous rencontrez le même problème lors de la mise à jour pour prendre en charge la version 26, voici le résumé de cette réponse .
la source
Julian Os a raison.
La réponse de Manolo Garcia ne fonctionne pas si la vue de recyclage est inférieure au seuil et défile. Vous devez comparer le
offset
de la vue de recyclage et levelocity to the distance
, pas la position de l'élément.J'ai fait la version java en faisant référence au code kotlin de Julian et en soustrayant la réflexion.
la source
BaseApplication
J'ai trouvé le correctif par Eniz Bilgin https://stackoverflow.com/a/45090239/7639018
Le problème a été résolu avec les bibliothèques de ce référentiel.
( https://developer.android.com/topic/libraries/support-library/setup.html )
la source
En référence à Google issue tracker , il a été corrigé avec la version Android 26.0.0-beta2 de la bibliothèque de support
Veuillez mettre à jour votre bibliothèque de support Android version 26.0.0-beta2.
Si un problème persiste, veuillez le signaler à l' outil de suivi des problèmes de Google qu'ils rouvriront pour examen.
la source
Ajouter une autre réponse ici car celles ci-dessus ne répondaient pas complètement à mes besoins ou ne fonctionnaient pas très bien. Celui-ci est en partie basé sur des idées répandues ici.
Alors que fait celui-ci?
Scénario fling vers le bas: si l'AppBarLayout est réduit, il laisse le RecyclerView se balancer sans rien faire. Sinon, il réduit l'AppBarLayout et empêche le RecyclerView de faire son fling. Dès qu'il est réduit (jusqu'à ce que la vitesse donnée l'exige) et s'il reste de la vitesse, le RecyclerView est projeté avec la vitesse d'origine moins ce que l'AppBarLayout vient de consommer.
Scénario vers le haut: si le décalage de défilement du RecyclerView n'est pas nul, il est projeté avec la vitesse d'origine. Dès que cela est terminé et s'il reste de la vitesse (c'est-à-dire que le RecyclerView défile jusqu'à la position 0), l'AppBarLayout est étendu au point que la vitesse d'origine moins les demandes juste consommées. Sinon, l'AppBarLayout est étendu au point que la vitesse d'origine l'exige.
AFAIK, c'est le comportement indendu.
Il y a beaucoup de réflexion en jeu, et c'est assez coutume. Aucun problème n'a encore été trouvé. Il est également écrit en Kotlin, mais le comprendre ne devrait pas poser de problème. Vous pouvez utiliser le plugin IntelliJ Kotlin pour le compiler en bytecode -> et le décompiler en Java. Pour l'utiliser, placez-le dans le package android.support.v7.widget et définissez-le comme le comportement de CoordinatorLayout.LayoutParams d'AppBarLayout dans le code (ou ajoutez le constructeur xml applicable ou quelque chose)
la source
c'est ma solution dans mon projet.
arrêtez simplement le mScroller lorsque vous obtenez Action_Down
xml:
FixAppBarLayoutBehavior.java:
la source
pour androidx,
Si votre fichier manifeste a une ligne android: hardwareAccelerated = "false", supprimez-la.
la source