本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
RelativeLayout
通过锚点为每个子组件定位——相对于容器或相对于另一个组件。它独有的强项是将 A 锚定到 B(头像角上的徽标、图标右侧的标签)。
🔴 · 包:
dev.crossfly.ui.layout· 继承自:Layout
何时使用
- 将一个组件锚定到另一个组件(
AFTER、BEFORE、END_OF、CENTER_OF)。 - 精细的叠加与组合(徽标、印章、定位的标签)。
何时不要使用
- “顶部/内容/底部填满剩余空间”的骨架 → 优先使用配合
LAY_FILL的 VerticalLayout(更简单;参见下方关于FILL/FIT的说明)。
add(...) — 签名与语义
public RelativeLayout add(Component alvo, RelPos x, RelPos y, RelSize larg, RelSize alt);
// + 重载: (..., Component ref) (..., Gap outgap) (..., Component ref, Gap outgap)
没有 ref 时,锚点相对于上一个添加的组件。
RelPos(位置,位于 UIConstants):START、CENTER、END、AFTER、BEFORE、CENTER_OF、
END_OF、SAMEPOS、AUTOPOS、AUTOPOSCENTERED、KEEPPOS。
RelSize(尺寸):AUTOSIZE、FILL、FIT、SAMESIZE、KEEPSIZE。
完整示例(复制、粘贴并运行)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.graphics.*;
/** 可执行的主界面。将 launcher 指向此类(classname)并运行:gradlew :lwjgl3:run */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
// 头像 + 头像角上的徽标 + 旁边的名字
RelativeLayout rl = new RelativeLayout();
Label avatar = new Label("👤");
avatar.getStyle().autoWidth(Relative.ofFont(3f)).autoHeight(Relative.ofFont(3f));
Label badge = new Label("9");
Label nome = new Label("Ana Silva");
rl.add(avatar, RelPos.START, RelPos.START, RelSize.AUTOSIZE, RelSize.AUTOSIZE);
rl.add(badge, RelPos.END_OF, RelPos.START, RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // 头像的角
rl.add(nome, RelPos.AFTER, RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // 头像之后
Component cabecalho = new Component();
cabecalho.setLayout(rl);
setLayout(new VerticalLayout(Position.START, Position.START));
add(LAY_AUTO, cabecalho);
add(LAY_FILL, new Component());
}
}
下面的片段只展示核心部分(放进
onShow()里的内容)。要运行它们,请将其放入上面的MainWindow骨架中。
基本用法
// 头像 + 头像角上的徽标 + 旁边的名字
RelativeLayout rl = new RelativeLayout();
ImageView avatar = new ImageView(/* 照片 */);
avatar.getStyle().autoWidth(Relative.ofFont(3f)).autoHeight(Relative.ofFont(3f));
Label badge = new Label("9");
Label nome = new Label("Ana Silva");
rl.add(avatar, RelPos.START, RelPos.START, RelSize.AUTOSIZE, RelSize.AUTOSIZE);
rl.add(badge, RelPos.END_OF, RelPos.START, RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // 头像的角
rl.add(nome, RelPos.AFTER, RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // 头像之后
Component cabecalho = new Component();
cabecalho.setLayout(rl);
有用的锚定模式
- B 在 A 右侧并对齐:
add(b, RelPos.AFTER, RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, a)。 - 与 A 相同尺寸:
RelSize.SAMESIZE。 - 居中卡片:
add(card, RelPos.CENTER, RelPos.CENTER, RelSize.AUTOSIZE, RelSize.AUTOSIZE)。 - 按规则设定边距: 将
Gap.ofFont(0.5f)作为最后一个参数传入(它会成为该规则的outgap)。
⚠️ RelSize 的确切语义(不要混淆)
FILL= 父容器的全部宽度/高度减去边距——忽略参照物(不是“A 旁边剩下的空间”)。FIT= 从父容器的角到参照物的边(例如:填充到 A 的左侧/顶部)。- 要实现“某个子组件吸收其他组件旁边的剩余空间” → 使用配合
LAY_FILL的HorizontalLayout/VerticalLayout,而不是RelativeLayout。
常见错误
- 期望
FILL是“A 旁边剩下的空间”(它其实是整个父容器)。 - 引用的循环(A 依赖 B,而 B 又依赖 A)——务必锚定到之前已经添加的组件。
另请参阅
- VerticalLayout(用于屏幕骨架) · 响应式设计
这个页面有帮助吗?感谢你的反馈!