This page was machine-translated from Portuguese and may contain errors. The Portuguese version is canonical.
10. Making it responsive
What you will learn: make the app adapt to any screen without a single fixed pixel. Prerequisites: Persisting data.
Complete example (copy, paste and run)
An adaptive app: onReposition() swaps the arrangement by orientation (2 columns in landscape, 1 in
portrait) without recreating state, using Relative/Gap and Screen. Compiles as is.
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
public class MainWindow extends Window
{
private final Component painel = new Component();
private final Component listaBox = new Component();
private final Component detalheBox = new Component();
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
listaBox.setLayout(new VerticalLayout());
listaBox.add(LAY_AUTO, new Label("Lista"));
detalheBox.setLayout(new VerticalLayout());
detalheBox.add(LAY_AUTO, new Label("Detalhe"));
boolean largo = Screen.minSize >= 600; // breakpoint: smaller side (stable on rotation)
add(LAY_AUTO, new Label(largo ? "Tablet/desktop" : "Telefone"));
add(LAY_FILL, painel);
onReposition(); // initial arrangement
}
@Override
protected void onReposition() throws Exception
{
painel.removeAll();
if (Screen.isLandscape) { // 2 columns: list | detail
painel.setLayout(new HorizontalLayout());
painel.add(0.4f, listaBox);
painel.add(0.6f, detalheBox);
} else { // 1 column
painel.setLayout(new VerticalLayout());
painel.add(LAY_FILL, listaBox);
}
painel.setValidLayout(false);
}
}
The snippets below show only the core (what goes inside
onShow()). To run them, place them in theMainWindowskeleton above.
The tools
Relative.ofFont(1.5f); // scales with the font/DPI
Relative.ofScreen(0.8f, ScreenSize.MIN); // fraction of the SMALLER side (adapts portrait/landscape)
Gap.ofFont(0.5f); // spacing that scales
add(LAY_FILL, comp); // one elastic area per axis
Breakpoint with Screen.minSize
Use the smaller side — stable when the device rotates:
boolean largo = Screen.minSize >= 600; // tablet/desktop
Swapping the arrangement by orientation — onReposition()
When the structure must change (1 column in portrait, 2 in landscape), override onReposition()
(called on resize) — without recreating state:
@Override protected void onReposition() throws Exception {
painel.removeAll();
if (Screen.isLandscape) { // 2 columns: list | detail
painel.setLayout(new HorizontalLayout());
painel.add(0.4f, listaBox);
painel.add(0.6f, detalheBox);
} else { // 1 column
painel.setLayout(new VerticalLayout());
painel.add(LAY_FILL, listaBox);
}
}
What you build in this step
The app becomes adaptive — phone in portrait, tablet/desktop in landscape — with no fixed pixels.
Recap
Relative/Gap/LAY_FILL = automatic responsiveness; Screen.minSize = breakpoint; onReposition()
swaps the arrangement while preserving state.