数据绑定
Rive 的 View Models 会暴露强类型属性(数字、字符串、颜色、布尔值、枚举、触发器、列表、嵌套视图模型、图像和画板引用),画板可以绑定到这些属性。在 C++ 中,你可以实例化一个视图模型、修改属性,绑定的视觉内容会在下一次 advanceAndApply 时更新。
概念
ViewModelRuntime— 在编辑器中定义的视图模型 schema。存在于File中。ViewModelInstanceRuntime— 该 schema 实例的类型化包装器。暴露属性 API(propertyNumber、propertyString等)。你通过rcp<>持有它。ViewModelInstance— 底层可绑定实例。Artboard和StateMachineInstance会绑定到这个类型。可通过ViewModelInstanceRuntime的.instance()获取。ViewModelInstance*Runtime— 各个属性的类型化句柄(…NumberRuntime、…StringRuntime等)。
创建实例
最简单的方式是向文件请求画板的默认视图模型,然后从中创建默认实例:
#include "rive/file.hpp"
#include "rive/viewmodel/runtime/viewmodel_runtime.hpp"
ViewModelRuntime* vm = file->defaultArtboardViewModel(artboard.get());
if (!vm) return; // artboard has no default view model
rcp<ViewModelInstanceRuntime> instance = vm->createDefaultInstance();
if (instance) {
artboard->bindViewModelInstance(instance->instance());
sm ->bindViewModelInstance(instance->instance());
}
如果需要完全控制,可以按索引或名称查找特定的视图模型 schema,并从中创建实例:
ViewModelRuntime* vm = file->viewModelByName("Card");
if (!vm) return; // no view model with that name
size_t propCount = vm->propertyCount();
size_t instCount = vm->instanceCount();
rcp<ViewModelInstanceRuntime> instance = vm->createDefaultInstance();
// alternatives — pick one and replace the line above:
// rcp<ViewModelInstanceRuntime> instance = vm->createInstanceFromName("Hero");
// rcp<ViewModelInstanceRuntime> instance = vm->createInstanceFromIndex(0);
// rcp<ViewModelInstanceRuntime> instance = vm->createInstance(); // no editor preset; properties at type defaults
if (!instance) return;
artboard->bindViewModelInstance(instance->instance());
sm ->bindViewModelInstance(instance->instance());
将同一个 ViewModelInstance 同时绑定到 画板 和 状态机。
画板绑定会驱动影响布局的属性;状态机绑定会驱动状态机转场和监听器条件。
读取和写入属性
所有访问器都基于路径 — 嵌套视图模型使用 / 分隔。
auto* card = instance.get();
// Number
if (auto* score = card->propertyNumber("score")) {
score->value(42.0f);
float v = score->value();
}
// String
if (auto* title = card->propertyString("title")) {
title->value("Hello");
}
// Boolean
if (auto* on = card->propertyBoolean("isOpen")) {
on->value(true);
}
// Color (ARGB packed)
if (auto* col = card->propertyColor("accent")) {
col->value(0xFFE53935);
}
// Trigger (edge event)
if (auto* fire = card->propertyTrigger("fire")) {
fire->trigger();
}
// Enum (by string label)
if (auto* mood = card->propertyEnum("mood")) {
mood->value("happy");
}