Me gustaría que un ScrollView comenzara en la parte inferior. Cualquier metodo?
Me gustaría que un ScrollView comenzara en la parte inferior. Cualquier metodo?
Respuestas:
scroll.fullScroll(View.FOCUS_DOWN)
También debería funcionar.
Pon esto en un scroll.Post(Runnable run)
Código Kotlin
scrollView.post {
scrollView.fullScroll(View.FOCUS_DOWN)
}
deberías ejecutar el código dentro del scroll.post así:
scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});
scroll.scrollTo(0, scroll.getHeight());
para saltar al fondo, o scroll.smoothScrollTo(0, scroll.getHeight());
para un desplazamiento más suave
scrollView.post { scrollView.fullScroll(View.FOCUS_DOWN) }
scroll.fullScroll(View.FOCUS_DOWN)
conducirá al cambio de enfoque. Eso traerá un comportamiento extraño cuando haya más de una vista enfocable, por ejemplo, dos EditText. Hay otra forma de esta pregunta.
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);
Esto funciona bien
Extensión Kotlin
fun ScrollView.scrollToBottom() {
val lastChild = getChildAt(childCount - 1)
val bottom = lastChild.bottom + paddingBottom
val delta = bottom - (scrollY+ height)
smoothScrollBy(0, delta)
}
A veces scrollView.post no funciona
scrollView.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
PERO si usa scrollView.postDelayed, definitivamente funcionará
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
},1000);
Lo que funcionó mejor para mí es
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());
}
});
Incremento para trabajar perfectamente.
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();
}
Nota
Esta respuesta es una solución para versiones realmente antiguas de Android. Hoy postDelayed
no tiene más ese error y debería usarlo.
postDelayed
:)
Lo intenté con éxito.
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.smoothScrollTo(0, scrollView.getHeight());
}
}, 1000);
Cuando la vista aún no está cargada, no puede desplazarse. Puede hacerlo 'más tarde' con una publicación o llamada de suspensión como se indicó anteriormente, pero esto no es muy elegante.
Es mejor planificar el desplazamiento y hacerlo en el siguiente onLayout (). Código de ejemplo aquí:
Una cosa a considerar es qué NO configurar. Asegúrese de que sus controles secundarios, especialmente los controles EditText, no tengan establecida la propiedad RequestFocus. Esta puede ser una de las últimas propiedades interpretadas en el diseño y anulará la configuración de gravedad en sus padres (el diseño o ScrollView).
Aquí hay otras formas de desplazarse hacia abajo
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()
}
Utilizando
Si desplaza la vista ya presentada
my_scroll_view.scrollToBottom()
Si su vista de desplazamiento no está terminada (por ejemplo: se desplaza hacia abajo en onCreate
Método de actividad ...)
my_scroll_view.post {
my_scroll_view.scrollToBottom()
}
No es exactamente la respuesta a la pregunta, pero necesitaba desplazarme hacia abajo tan pronto como un EditText tuviera el foco. Sin embargo, la respuesta aceptada haría que el ET también pierda el foco de inmediato (supongo que con ScrollView).
Mi solución fue la siguiente:
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();
}
}
});
De hecho, encontré que llamar a fullScroll dos veces es el truco:
myScrollView.fullScroll(View.FOCUS_DOWN);
myScrollView.post(new Runnable() {
@Override
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
Puede tener algo que ver con la activación del método post () justo después de realizar el primer desplazamiento (sin éxito). Creo que este comportamiento ocurre después de cualquier llamada a un método anterior en myScrollView, por lo que puede intentar reemplazar el primer método fullScroll () por cualquier otra cosa que pueda ser relevante para usted.
Usar hay otra forma genial de hacer esto con las corutinas de Kotlin. La ventaja de usar una rutina opuesta a un controlador con un ejecutable (post / postDelayed) es que no activa un hilo costoso para ejecutar una acción retrasada.
launch(UI){
delay(300)
scrollView.fullScroll(View.FOCUS_DOWN)
}
Es importante especificar el HandlerContext de la rutina como IU; de lo contrario, es posible que no se invoque la acción retrasada desde el hilo de la IU.
Una posible razón de por qué scroll.fullScroll(View.FOCUS_DOWN)
podría no funcionar incluso envuelto .post()
es que la vista no se presenta. En este caso, View.doOnLayout () podría ser una mejor opción:
scroll.doOnLayout(){
scroll.fullScroll(View.FOCUS_DOWN)
}
O, algo más elaborado para las almas valientes: https://chris.banes.dev/2019/12/03/suspending-views/