web-dev-qa-db-fra.com

FullScroll (View.FOCUS_UP) de NestedScrollView ne fonctionne pas correctement

J'ai un NestedScrollView peuplé d'un LinearLayout vertical, qui a lui-même un tas d'enfants de différents types de vues: plusieurs TextViews, deux GridViews statiques et même un FrameLayout pour montrer un fragment sous-jacent. 

Lorsque l'utilisateur appuie sur le bouton Précédent, si l'utilisateur a fait défiler son contenu sous un certain point au lieu de terminer l'activité, la méthode "scrollToTop" est appelée:

public static void scrollToTop(final NestedScrollView scrollview) {
    new Handler().postDelayed(new Runnable() {
        public void run() {
            scrollview.fullScroll(NestedScrollView.FOCUS_UP);
        }
    }, 200);
}

Cela fonctionne dans la version précédente de mon application, qui est dans le Play Store. Mais maintenant, après avoir mis à jour mon application pour cibler Android Oreo (et la mise à jour de la bibliothèque de support vers la version 26.0.2), au lieu de faire défiler l'écran vers le haut, il semble que le défilement commence en dessous de la position de défilement d'origine de NestedScrollView et s'arrête là où il était. Cela apparaît donc comme un bégaiement étrange. À certains endroits, cependant, il défile vers le haut (bien que très rarement et de façon incohérente), et d’autres vers le bas, pour la raison que je ne comprends pas.

J'ai expérimenté la mise au point en vue, en vain. Par exemple, j'ai lu que Static GridViews pouvait interrompre la mise au point lors du défilement. J'ai également essayé différentes méthodes de défilement, telles que

scrollview.pageScroll(View.FOCUS_UP);

et

scrollview.smoothScrollTo(0,0);

Mais rien ne semble fonctionner. Quelque chose ne va pas avec la bibliothèque de support cette fois-ci?

10
S Fitz

essaye ça

ajoutez Android:descendantFocusability="blocksDescendants" à la LinearLayout à l'intérieur de NestedScrollView et cela aussi 

pour faire défiler vers le haut de NestedScrollView utiliser ceci

NestedScrollView.scrollTo(0, 0);

Modifier

Utilisez fling() et smoothScrollTo togather 

nestedScrollView.post(new Runnable() {
   @Override
   public void run() {
      nestedScrollView.fling(0);
      nestedScrollView.smoothScrollTo(0, 0);
   }
});
14
Nilesh Rathod

UPDATE:

Trouvé une meilleure solution. Essayez ce combo:

scrollView.fling(0);  // Sets mLastScrollerY for next command
scrollView.smoothScrollTo(0, 0);  // Starts a scroll itself

Ressemble à un hack, mais fonctionne bien sur mes deux appareils (testé avec Support Library 26.0.0 & 27.0.2). Peut être utilisé pour faire défiler en douceur vers n'importe quelle autre position. Basé sur l'idée que le problème réside dans mise à jour manquante de mLastScrollerY .

S'il vous plaît laissez un commentaire si cela fonctionne pour vous ou non.

Réponse originale:

Hit cette question aussi.

NestedScrollView.smoothScrollTo(0, 0) a fonctionné jusqu'à 25.4.0 dans la bibliothèque de support technique et ne fonctionne plus depuis le 26.0.0 jusqu'au 27.0.2 actuel. Le contenu de NestedScrollView n'a pas d'importance (certaines TextViews suffisent).

Ce bogue est déjà signalédeux fois sur Google Issue Tracker. Le projet minimal pour le reproduire se trouve sur GitHub .

Trouvé deux solutions de travail:

  1. NestedScrollView.scrollTo(0, 0) (voir réponse acceptée, saute brusquement)
  2. NestedScrollView.fling(-10000) (défile doucement, mais la valeur de vélocité appropriée dépend de la position actuelle, du périphérique, du temps de défilement souhaité, etc.)

Il n'était pas nécessaire de changer la focalisation dans mon cas.

13
gmk57

Ce code fonctionne pour moi.

scrollView.post {
    scrollView.fling(0)
    scrollView.fullScroll(ScrollView.FOCUS_UP)
}
3
WuHaojie

Il semble que ce soit finalement résolu dans la librairie de support 28.0.0, donc NestedScrollView.smoothScrollTo() fonctionne comme prévu pour moi

0
Konstantin Konopko