Package com.ultikits.ultitools.abstracts.gui.declarative
本框架基于 Flutter 的设计理念,提供声明式的 UI 构建方式。 核心理念:UI = f(state)
⚠ 当前状态(6.2.5)
本包及其子包标记为 @ApiStatus.Experimental,API 可能在任何版本发生不兼容变动。
状态驱动的重绘尚未实现。UI = f(state) 是本框架的设计目标,但渲染引擎的三个接缝
目前都还没接上:build(BuildContext) 只在 onOpen 中被调用一次;
Element.update() 不置脏标记;State.setState 的信号沿 Element 树上溯到根节点后
静默终止,进不了调度器。因此下面「主要特性」中的 setState 触发局部重建 目前不生效,
依赖 setState 的导航子系统(Navigator.push / pop)同样惰性。
现阶段可靠可用的是静态页面:build 一次、渲染一次。
State-driven repaint is not implemented yet. UI = f(state) is the design
goal, but all three rendering seams are still open: build(BuildContext) is called
exactly once from onOpen; Element.update() never marks anything dirty; and
the State.setState signal walks up the element tree and stops silently at the root
without reaching the scheduler. The setState triggers a partial rebuild bullet below
therefore does not hold today, and the navigation subsystem is inert for the same reason.
What works today is the static page: build once, render once.
修复排期见 issue #200(6.3.0)。
主要特性:
- Widget 树描述 UI 结构
- Element 树管理 Widget 实例和生命周期
- RenderNode 树进行高效的 diff 更新
- 支持 StatelessWidget 和 StatefulWidget
- setState 触发局部重建
- 所有更新自动在主线程执行
- 兼容 obliviate-invs 的 Gui 生命周期
快速开始:
// 1. 创建你的 GUI 页面
public class ShopPage extends DeclarativeGui {
private final List<ItemStack> items;
public ShopPage(Player player, List<ItemStack> items) {
super(player, "shop", "Item Shop", 6);
this.items = items;
}
@Override
public Widget build(BuildContext context) {
return Container.builder()
.background(IconWrapper.builder(glassPane).name(" ").build())
.children(
// 标题
TextButton.builder()
.text("§6§lItem Shop")
.slot(4)
.build(),
// 物品网格
GridView.<ItemStack>builder()
.startSlot(10)
.columns(7)
.rows(4)
.items(items, item -> ItemDisplay.builder(item)
.onClick(() -> buyItem(item))
.build())
.build(),
// 关闭按钮
TextButton.builder()
.text("§cClose")
.color("RED")
.slot(49)
.onClick(player::closeInventory)
.build()
)
.build();
}
private void buyItem(ItemStack item) {
// 处理购买逻辑
}
}
// 2. 打开 GUI
new ShopPage(player, items).open();
StatefulWidget 示例:
public class CounterPage extends DeclarativeGui {
private int count = 0;
public CounterPage(Player player) {
super(player, "counter", "Counter", 3);
}
@Override
public Widget build(BuildContext context) {
return Container.builder()
.child(TextButton.builder()
.text("Count: " + count)
.slot(13)
.onClick(() -> {
// 修改状态并触发重建
count++;
markNeedsBuild();
})
.build())
.build();
}
}
包结构:
- Since:
- 6.2.0
- Version:
- 1.0.0
- Author:
- qianmo
- See Also: