跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用
全部示例
配方布局列表97 行 · 1 个文件

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.

它展示了什么

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.

在你的机器上运行

每个示例都是普通的 Window,启动器只需要它的名字。

gradlew lwjgl3:run --args="classname dev.cf.recipe.R15Header"
修改它

Java 是提前编译的,浏览器无法自行重建你的修改 —— 这里的代码在发布前已由 TeaVM 转成 JavaScript。把文件复制到项目里,它在四个平台上原样运行;上面那条命令就是全部准备工作。

正在此处运行CrossFly 0.1.32
正在启动应用…

由 TeaVM 编译为 JavaScript —— 是同一份代码,不是录像。 · 全部示例

它用到了什么

本示例触及的框架类型。带链接的有参考页。

CardCollapsibleCollapsingHeaderComponentGapGridLayoutMaterialIconRelativeStylesTextFieldVerticalLayoutWidgets

源码

完整无删减。这就是那个文件,不是片段。

原始
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;
   }
}
给 AI 助手

本页的机器可读版本,让模型直接读取示例集,而不是猜测 API。

本示例(JSON)本示例(Markdown)
上一个Cards that reflow下一个Charts