Esta página fue traducida automáticamente del portugués y puede contener errores. La versión en portugués es la canónica.
Cómo hacer un Component desplazable y ajustar el overscroll
Propósito. Cualquier Component puede convertirse en un contenedor desplazable: basta declarar la dirección con
setScrollable(ScrollDirection). Si el contenido (la suma de las alturas de los hijos) excede el área
visible, el ScrollEngine se encarga de pan, momentum, fling y del overscroll (efecto elástico al
tirar más allá del límite).
APIs usadas
Component.setScrollable(ScrollDirection dir, ScrollEngine... engine)— habilita scroll.enginees opcional (default:ScrollEnginenuevo). Pasanullcomodirpara deshabilitar.UIConstants.ScrollDirection— enum con tres valores:HORIZONTAL,VERTICAL,BOTH.Component.isScrollable()— si el componente está desplazable.Component.scrollable()— retorna el objetoScrollable(con.engine), onull.Component.setShowScrollPosition(boolean)— muestra/oculta el indicador de posición de scroll.ScrollEngine.setOverscroll(boolean x, boolean y)— activa/desactiva el efecto elástico por eje. Default: ambostrue.ScrollEngine.setupOverscroll(float distance, float speedMin, float speedMax)— ajusta distancia y velocidad de retorno del overscroll.ScrollEngine.setScrollListener(ScrollListener listener)— callback en cada cambio de offset (recibevx, vy).ScrollEngine.scrollTo(float x, float y)/scrollToStartSmooth()/scrollToEndSmooth()— reposiciona el scroll.ScrollEngine.setOverscrollEffect(OverscrollEffect effect)— estático: define/desactiva (null) la curva gris de borde global; personalizable vianew OverscrollEffect().setColor(...).setMaxAlpha(...).setMaxArcHeight(...).
Ejemplo completo (copiar, pegar y ejecutar)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
Component painel = new Component();
painel.setLayout(new GridLayout(Position.CENTER, Position.START));
for (int i = 0; i < 60; i++)
painel.add(.95f, new Label("Linha " + i));
painel.setScrollable(ScrollDirection.VERTICAL); // desplaza en el eje Y
// ajustes opcionales en el motor de scroll:
painel.scrollable().engine.setOverscroll(true, false); // elástico solo en la vertical
painel.setShowScrollPosition(true); // indicador de posición
painel.scrollable().engine.setScrollListener((vx, vy) ->
Debug.log("scrollY = " + vy)); // reacciona al scroll
add(LAY_FILL, painel);
}
}
El fragmento de abajo muestra solo el núcleo. Para ejecutarlo, colócalo en el esqueleto
MainWindowde arriba.
Fragmento mínimo
// verificado en la fuente: Component.setScrollable (línea ~1027) + ScrollEngine.java
Component painel = new Component();
painel.setLayout(new GridLayout(Position.CENTER, Position.START));
for (int i = 0; i < 60; i++)
painel.add(.95f, new Label("Linha " + i));
painel.setScrollable(ScrollDirection.VERTICAL); // desplaza en el eje Y
// ajustes opcionales en el motor de scroll:
painel.scrollable().engine.setOverscroll(true, false); // elástico solo en la vertical
painel.setShowScrollPosition(true); // indicador de posición
painel.scrollable().engine.setScrollListener((vx, vy) ->
Debug.log("scrollY = " + vy)); // reacciona al scroll
layout.add(1f, painel);
Reposicionando por código:
painel.scrollable().engine.scrollToStartSmooth(); // vuelve al tope con animación
painel.scrollable().engine.scrollTo(0, 500); // salta al offset y=500 px
Nota honesta: no hay pull-to-refresh listo
El framework no ofrece un widget de “pull-to-refresh” (tirar-para-actualizar) listo. Lo que
existe es el efecto de overscroll (curva elástica al tirar más allá del límite), que es puramente
visual/físico — no expone un callback de “soltó después de tirar X píxeles” para que dispares
un refresh. Si necesitas ese comportamiento, tendrás que construirlo manualmente monitoreando el offset
via setScrollListener y detectando el overscroll más allá de un umbral. Para listas grandes con
recarga de datos, prefiere VirtualListView.reloadData() accionado por un botón o gesto propio.
Profundiza
- Las listas enormes ya vienen desplazables por defecto (el
VirtualListViewllama asetScrollable(VERTICAL)internamente): mira lista-virtual-grande.md.