web-dev-qa-db-fra.com

Android: ScrollView force vers le bas

Je voudrais un ScrollView pour commencer tout en bas. Toutes les méthodes?

151
Noah Seidman

scroll.fullScroll(View.FOCUS_DOWN) devrait également fonctionner.

208
CommonsWare

vous devriez lancer le code dans le scroll.post comme ceci:

scroll.post(new Runnable() {            
    @Override
    public void run() {
           scroll.fullScroll(View.FOCUS_DOWN);              
    }
});
294
hungson175

scroll.fullScroll(View.FOCUS_DOWN) entraînera le changement de focus. Cela entraînera un comportement étrange quand il y aura plus d'une vue, par exemple deux EditText. Il y a un autre moyen pour cette question.

    View lastChild = scrollLayout.getChildAt(scrollLayout.getChildCount() - 1);
    int bottom = lastChild.getBottom() + scrollLayout.getPaddingBottom();
    int sy = scrollLayout.getScrollY();
    int sh = scrollLayout.getHeight();
    int delta = bottom - (sy + sh);

    scrollLayout.smoothScrollBy(0, delta);

Ça marche bien.

50
peacepassion

Ce qui a fonctionné le mieux pour moi est 

scroll_view.post(new Runnable() {
     @Override
     public void run() {
         // This method works but animates the scrolling 
         // which looks weird on first load
         // scroll_view.fullScroll(View.FOCUS_DOWN);

         // This method works even better because there are no animations.
         scroll_view.scrollTo(0, scroll_view.getBottom());
     }
});
34
https

Parfois, scrollView.post ne fonctionne pas

 scrollView.post(new Runnable() {
        @Override
        public void run() {
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);
        }
    });

MAIS si vous utilisez scrollView.postDelayed, cela fonctionnera certainement

 scrollView.postDelayed(new Runnable() {
        @Override
        public void run() {
            scrollView.fullScroll(ScrollView.FOCUS_DOWN);
        }
    },1000);
29
Ajay Shrestha

J'incrémente pour fonctionner parfaitement.

    private void sendScroll(){
        final Handler handler = new Handler();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {Thread.sleep(100);} catch (InterruptedException e) {}
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        scrollView.fullScroll(View.FOCUS_DOWN);
                    }
                });
            }
        }).start();
    }

Remarque

Cette réponse est une solution de contournement pour les très anciennes versions d’Android. Aujourd'hui, le postDelayed n'a plus ce bogue et vous devriez l'utiliser.

27
ademar111190

Lorsque la vue n'est pas encore chargée, vous ne pouvez pas faire défiler. Vous pouvez le faire "plus tard" avec un post ou un appel de sommeil comme ci-dessus, mais ce n'est pas très élégant. 

Il est préférable de planifier le défilement et de le faire à la prochaine étape onLayout (). Exemple de code ici:

https://stackoverflow.com/a/10209457/1310343

3
Frank

Une chose à considérer est ce qui ne doit pas être défini. Assurez-vous que vos contrôles enfants, en particulier les contrôles EditText, ne possèdent pas la propriété RequestFocus. Il peut s’agir d’une des dernières propriétés interprétées de la présentation et elle remplacera les paramètres de gravité de ses parents (la disposition ou ScrollView).

3
Epsilon3

Pas exactement la réponse à la question, mais je devais faire défiler le texte dès qu'un EditText avait le focus. Cependant, la réponse acceptée ferait perdre également la focalisation de l'ET (à la ScrollView, je suppose). 

Ma solution de contournement était la suivante:

emailEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus){
            Toast.makeText(getActivity(), "got the focus", Toast.LENGTH_LONG).show();
            scrollView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    scrollView.fullScroll(ScrollView.FOCUS_DOWN);
                }
            }, 200);
        }else {
            Toast.makeText(getActivity(), "lost the focus", Toast.LENGTH_LONG).show();
        }
    }
});
1
Teo Inke

En fait, j'ai trouvé qu'appeler fullScroll à deux reprises faisait l'affaire:

myScrollView.fullScroll(View.FOCUS_DOWN);

myScrollView.post(new Runnable() {
    @Override
    public void run() {
        myScrollView.fullScroll(View.FOCUS_DOWN);
    }
});

Cela peut avoir quelque chose à voir avec l'activation de la méthode post () juste après avoir effectué le premier défilement (non réussi). Je pense que ce problème se produit après tout appel de méthode précédent sur myScrollView. Vous pouvez donc essayer de remplacer la première méthode fullScroll () par tout ce qui pourrait vous intéresser.

1
BarLr

Voici quelques autres moyens de faire défiler vers le bas

fun ScrollView.scrollToBottom() {
    // use this for scroll immediately
    scrollTo(0, this.getChildAt(0).height) 

    // or this for smooth scroll
    //smoothScrollBy(0, this.getChildAt(0).height)

    // or this for **very** smooth scroll
    //ObjectAnimator.ofInt(this, "scrollY", this.getChildAt(0).height).setDuration(2000).start()
}

En utilisant

Si vous avez déjà vu défiler

my_scroll_view.scrollToBottom()

Si votre vue de défilement n'est pas finie (par exemple: vous faites défiler vers le bas dans la méthode Activity onCreate ...)

my_scroll_view.post { 
   my_scroll_view.scrollToBottom()          
}
0
Phan Van Linh

Il existe un autre moyen intéressant de le faire avec les coroutines Kotlin. L'avantage d'utiliser une coroutine opposée à un gestionnaire avec un exécutable (post/postDelayed) est qu'il ne lance pas de thread coûteux pour exécuter une action retardée.

launch(UI){
    delay(300)
    scrollView.fullScroll(View.FOCUS_DOWN)
}

Il est important de spécifier le HandlerContext de la coroutine en tant qu'UI, sinon l'action différée pourrait ne pas être appelée à partir du fil de l'interface utilisateur.

0
Phaestion

Dans ce cas, utilisez seulement scroll.scrollTo (0, sc.getBottom ()) ne fonctionne pas, utilisez-le avec scroll.post

Exemple:

scroll.post(new Runnable() {
  @Override
  public void run() {
  scroll.fullScroll(View.FOCUS_DOWN);
  } 
});
0
nnyerges