本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
7. 管理状态
你将学到: CrossFly 的状态模型 —— 这里是来自 Flutter/React 的人需要忘却重学之处。前置条件: 处理输入。
完整示例(复制、粘贴、运行)
一个轻量的 ViewModel(TarefaVM),带手动的 observe(Runnable)(没有响应式绑定):当状态变化时 View 重新填充组件。一个按钮添加任务,列表随之重新渲染。可直接编译运行。
package com.exemplo;
import java.util.*;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
public class MainWindow extends Window
{
private final TarefaVM vm = new TarefaVM();
private final Component listaBox = new Component();
private int contador = 1;
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
Button add = new Button("Adicionar tarefa");
add.onAction(c -> vm.adicionar(new Tarefa("Tarefa " + (contador++))));
add(LAY_AUTO, add);
listaBox.setLayout(new VerticalLayout());
add(LAY_FILL, listaBox);
vm.observe(this::renderizarLista); // 状态变化时重新填充
renderizarLista();
}
private void renderizarLista()
{
listaBox.removeAll();
for (Tarefa t : vm.tarefas) listaBox.add(LAY_AUTO, new Label(t.titulo));
listaBox.setValidLayout(false); // 尺寸已改变
Component.repaint();
}
}
class Tarefa
{
final String titulo;
Tarefa(String titulo) { this.titulo = titulo; }
}
class TarefaVM
{
private Runnable onChange;
public List<Tarefa> tarefas = new ArrayList<>();
public void observe(Runnable r) { this.onChange = r; }
private void mudou() { if (onChange != null) onChange.run(); }
public void adicionar(Tarefa t)
{
var novo = new ArrayList<>(tarefas); novo.add(t);
tarefas = novo;
mudou(); // 通知 View(在 paint thread 上)
}
}
下面的片段只展示核心部分(放在
onShow()里的内容)。要运行,请把它们放进上面的MainWindow骨架里。
没有响应式绑定
修改模型不会自动更新 UI。状态存活于字段(或一个轻量的 ViewModel)中,而 View 手动将状态 → 组件翻译,调用 repaint()(如果尺寸变化了,还要调用 setValidLayout(false))。
一个带 observe 的轻量 ViewModel
public class TarefaVM {
private Runnable onChange;
public List<Tarefa> tarefas = List.of();
public void observe(Runnable r) { this.onChange = r; }
private void mudou() { if (onChange != null) onChange.run(); }
public void adicionar(Tarefa t) {
var novo = new ArrayList<>(tarefas); novo.add(t);
tarefas = novo;
mudou(); // 通知 View(在 paint thread 上)
}
}
View 做出反应
@Override public void onShow() throws Exception {
super.onShow();
// … 构建 UI …
vm.observe(this::renderizarLista); // 状态变化时重新填充组件
vm.carregar(); // 触发加载(在后台 — 下一章)
}
private void renderizarLista() {
listaBox.removeAll();
for (Tarefa t : vm.tarefas) { CardTarefa card = new CardTarefa(); listaBox.add(LAY_AUTO, card); card.bind(t); }
listaBox.setValidLayout(false);
Component.repaint();
}
规则:修改和通知始终在绘制线程上进行。如果数据来自后台,在改动 View 读取的状态之前,先进入
Component.onUI(...)(见下一章)。
本步骤所构建的
TarefaVM 以及在状态变化时会重新渲染的界面。
回顾
无响应式:状态存于字段/ViewModel;View 用 repaint() 将状态→组件翻译;一个手动的 observe(Runnable) 替代了绑定。
下一步
→ 加载数据
另见
这个页面有帮助吗?感谢你的反馈!