跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

所有布局中的响应式设计

CrossFly 使用逻辑像素,并在旋转/调整尺寸时重新计算布局。如果你遵循下面的原则,屏幕会自行重新适配——无需编写 resize 代码。

这是实用摘要。带有每种布局示例以及端到端屏幕示例的完整指南,是第 36 章——布局与响应式设计最佳实践。

5 条原则

  1. 绝不使用固定像素定位。 使用分数、Relative 以及 LAY_FILL/LAY_AUTO / RelSize.FILL。
  2. 让布局来测量。 LAY_AUTO、RelSize.AUTOSIZE 和 Relative.AUTO 会报告自然尺寸。
  3. 间距也要缩放。 通过 Gap.ofFont(...) / Gap.ofScreen(...) 设置内边距(ingap)和外边距(outgap)。
  4. 一个“弹性”区域。 将一个组件标记为 LAY_FILL(Vertical/Horizontal)以吸收剩余空间。
  5. Resize 是自动的——只要你使用了上述各项。只有手动定位(setBounds)才需要代码。

核心工具:Relative

形式 结果
Relative.ofFont(1.5f) 1.5 × 字体高度(随字体/DPI 缩放)
Relative.ofScreen(0.8f) 屏幕尺寸的 80%
Relative.ofScreen(0.5f, ScreenSize.MIN) 较小边的 50%(适配竖屏/横屏)
Relative.FULL / AUTO / CENTER 填满父容器 / 内容尺寸 / 居中

完整示例(复制、粘贴并运行)

package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   private Component painel;      // 每次 resize/旋转都会重新排列
   private Component lista;
   private Component detalhe;

   @Override
   public void onShow() throws Exception
   {
      super.onShow();

      lista   = new Label("Lista");
      detalhe = new Label("Detalhe");

      painel = new Component();
      setLayout(new VerticalLayout(Position.START, Position.START));
      add(LAY_FILL, painel);
      // onReposition() 在首次布局及每次 resize/旋转时被调用:
      // 它根据方向选择面板的布局方式。
   }

   @Override
   protected void onReposition() throws Exception
   {
      painel.removeAll();
      if (Screen.isLandscape) {
         painel.setLayout(new HorizontalLayout());
         painel.add(0.5f, lista); painel.add(0.5f, detalhe);
      } else {
         painel.setLayout(new VerticalLayout());
         painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
      }
   }
}

下面的片段只展示核心部分(放进 onShow() 里的内容)。要运行它们,请将其放入上面的 MainWindow 骨架中。

当排布应随方向而改变时

覆盖 Window.onReposition()(在重新布局之前调用)并重新选择布局:

@Override protected void onReposition() throws Exception {
   painel.removeAll();
   if (Screen.isLandscape) {
      painel.setLayout(new HorizontalLayout());
      painel.add(0.5f, lista); painel.add(0.5f, detalhe);
   } else {
      painel.setLayout(new VerticalLayout());
      painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
   }
}

断点: 使用 Screen.minSize(较小边在不同方向间是稳定的),例如:tablet = Screen.minSize >= 600。

另请参阅

这个页面有帮助吗?