Saltar al contenido
CrossFly es 100% open sourceSíguenos en GitHub
CrossFlyCrossFly
Empezar
Todos los ejemplos
RecetasDisposiciónListas97 líneas · 1 archivos

A header that collapses

header() scrolls away, pinned() never does. Put the identity in the first and the control the reader needs at row 200 in the second.

Qué muestra esto

A header that gets out of the way, and a section that folds.

Two different problems that look alike. CollapsingHeader is about room: the title and the summary matter when you arrive and stop mattering once you are reading, so they shrink as you scroll while the search box stays pinned. Collapsible is about attention: the content is always relevant, and the reader decides when to look at it.

Scroll the list to see the first one work — the pinned row does not move.

Ejecutarlo en tu máquina

Cada ejemplo es una Window normal, así que el lanzador solo necesita su nombre.

gradlew lwjgl3:run --args="classname dev.cf.recipe.R15Header"
Editarlo

Java se compila antes de ejecutarse, así que el navegador no puede reconstruir una edición por su cuenta: el código que ves aquí se convirtió en JavaScript con TeaVM antes de publicarse. Copia el archivo a un proyecto y funciona sin cambios en las cuatro plataformas; el comando de arriba es toda la preparación.

Ejecutándose aquíCrossFly 0.1.32
Iniciando la aplicación…

Compilado a JavaScript por TeaVM: es el mismo código, no un vídeo de él. · Todos los ejemplos

Qué usa

Tipos del framework que toca este ejemplo. Los enlazados tienen página de referencia.

CardCollapsibleCollapsingHeaderComponentGapGridLayoutMaterialIconRelativeStylesTextFieldVerticalLayoutWidgets

El código

Completo, sin recortes. Es el archivo, no un fragmento.

Crudo
dev/cf/recipe/R15Header.java
package dev.cf.recipe;

import dev.cf.Tones;

import dev.crossfly.ui.*;
import dev.crossfly.ui.color.*;
import dev.crossfly.ui.graphics.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;

import static dev.crossfly.ui.Widgets.*;

/**
 * A header that gets out of the way, and a section that folds.
 *
 * <p>Two different problems that look alike. {@link CollapsingHeader} is about <b>room</b>: the
 * title and the summary matter when you arrive and stop mattering once you are reading, so they
 * shrink as you scroll while the search box stays pinned. {@link Collapsible} is about
 * <b>attention</b>: the content is always relevant, and the reader decides when to look at it.</p>
 *
 * <p>Scroll the list to see the first one work — the pinned row does not move.</p>
 */
public class R15Header extends Recipe
{
   public String title()
   {
      return "A header that collapses";
   }

   public String note()
   {
      return "header() scrolls away, pinned() never does. Put the identity in the first and the"
         + " control the reader needs at row 200 in the second.";
   }

   public void build(Component body) throws Exception
   {
      CollapsingHeader ch = new CollapsingHeader();
      // A share of the screen, not 18 font heights: on an iPhone 5s 18 fonts were 612 of 1136 px, the
      // recipe outgrew the screen, and a drag past the end of the list scrolled the recipe instead -
      // sliding the "pinned" search under the top edge, cut (17/10/2026). A collapsing header must fit
      // the screen it collapses on; this one now does on any size, and follows a rotation.
      ch.getStyle()
         .autoHeight(Relative.ofScreen(.52f));

      Component head = new Component();
      head.setLayout(new VerticalLayout(Position.START, Position.START));
      head.add(LAY_AUTO, label("Northgate Industrial", 2f, true, Styles.textColor, Position.START));
      head.add(LAY_AUTO, outgap(label("412 parts · Leeds · account since 2019", 1f, false,
         Styles.captionColor, Position.START), 0, .2f, 0, 0));
      ch.header(head);

      TextField search = new TextField();
      search.caption("Search parts…");
      search.leftIcon(MaterialIcon.of(0xE8B6));
      ch.pinned(outgap(search, 0, .4f, 0, .4f));

      Component list = new Component();
      list.setLayout(new VerticalLayout(Position.START, Position.START));
      for (int i = 1; i <= 14; i++)
         list.add(LAY_AUTO, row("Part " + (100 + i), i));
      ch.content(list);
      ch.testTag("recipe.header");
      body.add(LAY_AUTO, ch);

      // ── The other one: folding by choice, not by scroll ──
      Collapsible more = new Collapsible(0xE8B8, Styles.primaryColor, "Delivery terms",
         "Collection, cut-off times");
      // Closed to start with: a section that folds is only worth having if the reader gets to
      // decide, and one that opens itself has answered the question for them.
      more.open(false);
      more.testTag("header.more");
      more.body()
         .add(LAY_AUTO, label("Standard delivery is five working days. Collection is available from"
            + " the trade counter until 17:00.", 1f, false, Styles.textColor, Position.START));
      body.add(LAY_AUTO, outgap(more, 0, 1f, 0, 0));
   }

   private Component row(String name, int i) throws Exception
   {
      Card c = new Card();
      c.setLayout(new GridLayout(Position.START, Position.CENTER));
      c.getStyle()
         .outgap(Gap.ofFont(0, 0, 0, .4f));

      Component t = new Component();
      t.setLayout(new VerticalLayout(Position.START, Position.START));
      t.add(LAY_AUTO, label(name, 1.2f, true, Styles.textColor, Position.START));
      t.add(LAY_AUTO, label("Part number", 1f, false, Styles.captionColor, Position.START));

      // The count is what a stock row is FOR, and it was the smallest, palest thing on it.
      c.add(0f, 1f, 0f, Tones.tile(0xE179, Tones.cycle(i)), outgap(t, .6f, 0, 0, 0),
         toneBadge(Tones.accent(), i * 7 + " in stock"));
      return c;
   }
}
Para una IA

Versiones de esta página legibles por máquina, para que un modelo lea el estante en vez de adivinar la API.

Este ejemplo, en JSONEste ejemplo, en Markdown
AnteriorCards that reflowSiguienteCharts