方向与间距 — 不用坐标的排布

5 分钟
目标画面课程第 2 讲。放多个元素看似需要坐标,但 linear 只收方向和间距。不用坐标不是口味,是条件。

第 1 讲的画面有三个节点,每个只带一个子节点。真实画面不是这样。

装多个的节点

{ "type": "linear", "direction": "vertical", "spacing": 12, "alignment": "center",
  "children": [ ... ] }

linear 收 children,只决定三件事。

  • direction — vertical 或 horizontal
  • spacing — 彼此之间的间距
  • alignment — 交叉轴上的对齐

想横着排,就改这个节点的 direction。子节点不动。

{ "type": "linear", "direction": "horizontal", "spacing": 16,
  "children": [
    { "type": "box", "width": 90, "height": 56, "decoration": { "color": "#ede9fe", "borderRadius": 10 } },
    { "type": "box", "width": 90, "height": 56, "decoration": { "color": "#ddd6fe", "borderRadius": 10 } },
    { "type": "box", "width": 90, "height": 56, "decoration": { "color": "#c4b5fd", "borderRadius": 10 } } ] }

box 是有尺寸和外观的方块。给它子节点,它就是那个子节点的容器;不给,它就是一块上了色的面。上面三个都没有子节点。

没有坐标

这份画面定义里,top、left、x、y 一个都没有。不是运行时偷懒。

画面来自服务器,意味着 写画面的那一方并不知道它将落在多大的地方。这个 906 字节的文件,在 1000 像素宽下、在平板上、在被拖到一半宽的桌面窗口里,都是同一个文件。写死坐标,就只在其中一种情况下对。

方向和间距不需要知道尺寸就能写。所以这一层只有它们。

检查 — 出现坐标就失败

grep -qE '"(top|left|right|bottom|x|y|dx|dy)"' screens/step2.json && \
  die "step2: the layout is positioned by hand"
grep -q '"direction"' screens/step2.json || die "step2: no direction"
grep -q '"spacing"' screens/step2.json || die "step2: no gap"

第一行和后两行方向相反:第一行 有则失败,后两行 无则失败。

需要这项检查,是因为光看渲染结果分辨不出。用坐标摆也能出眼下这张图 — 只要窗口尺寸不变。

渲染

step2  906 B, 12 lines, type "page" -> step2.png

竖向 linear 里有两行字和一个横向 linear,横向里三个不同颜色的方块。spacing 一处 12、一处 16,两层的疏密看得出差别。

尺寸写到哪一步

box 上写了 width、height。不是坐标,但确实是绝对值。

这条线在实务中会变模糊。判据只有一句:需要知道外部才能定的值,不写进画面定义。 方块的尺寸是方块自身的属性,可以写;方块的位置要知道兄弟和父级才定得下来,交给 linear。

自己跑一遍

cd content/sample/course-ui
bash verify.sh
open captures/step2.png

把 screens/step2.json 里的 "direction": "horizontal" 改成 "vertical" 再跑,三个方块就竖起来了。宿主一行都不用动。

带走的

  1. linear — direction·spacing·alignment
  2. box — 尺寸和外观,子节点可选
  3. 禁坐标的检查 — 渲染结果分辨不出,所以去看定义

下一讲

到这里画面还是固定的,只显示文件里写着的字。接下来是:文件里没有的值怎么出现在画面上。

运行示例

makemind-academy/course_ui/
git clone https://github.com/makemind-academy/course_ui
cd course_ui
bash verify.sh
在 GitHub 上打开 →