Je voudrais un ScrollView pour commencer tout en bas. Toutes les méthodes?
scroll.fullScroll(View.FOCUS_DOWN)
devrait également fonctionner.
vous devriez lancer le code dans le scroll.post comme ceci:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
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.
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());
}
});
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);
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.
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:
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).
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();
}
}
});
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.
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()
}
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.
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);
}
});