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

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

状态与数据流

对于来自 Flutter、Compose、SwiftUI 或 React 的人来说,这里最令人意外。有两处 刻意的缺失:

  • 没有自动的响应式绑定。 没有 setState、可观察对象、@State 或重组。改变 模型不会自动更新 UI。
  • 没有依赖注入容器。 没有 Dagger/Guice/Spring。你手动构建并传递你的 依赖(通常通过屏幕的构造函数)。

模型:命令式 + 显式失效

你读/写模型、直接更新组件,然后框架重绘:

model.nome = "Ana";
label.setText(model.nome);   // 大多数 setter 已使布局失效并调用 repaint()

大多数组件的 setter 已经替你触发 repaint()/使布局失效。需要记住的 唯一规则:

改了框架不知道的状态(你自己的一个计数器、一次计算、一个在 onPaint 中绘制的字段)?你来调用 repaint()。(参见 paint thread。)

经典反例

this.progresso = 0.7f;   // 我改了一个只有我的 onPaint 会读的字段…
// …而界面没变。缺少:
Component.repaint();      // ✔ 现在下一帧会反映新值

“我改了状态,屏幕却没更新”几乎总是缺了一个 repaint()。

为什么这样选择

  • 可预测性: 流程是线性且可见的 —— 数据 → setter → repaint → 帧。没有 神奇的重组,也没有隐藏的响应式循环需要调试。
  • 零魔法,低成本: 没有响应式依赖图,也没有要配置的 DI 框架。
  • 代价是显式性:管理状态是应用的职责,而非框架的。

框架提供的通信机制

  • 回调 / actions —— onAction(...)、通过构造函数传入的回调(参见 返回值)。
  • 父/子层级 —— 遍历组件树。
  • property(k, v) —— 每个组件的“数据袋”(参见 一切都是 Component)。
  • 全局状态 —— 在合理时使用静态字段/共享服务。

推荐的范式

由于框架只提供构件,组织范式(每个屏幕一个 ViewModel/controller + 用于数据的仓库)是应用层的约定 —— 记录于 best-practices。框架不强加架构;它提供 组件以及 setter→repaint() 这一对。

读取

setText / setItems

repaint

onAction

模型 / 仓库

ViewModel (你的)

Component

下一帧

参见

这个页面有帮助吗?