入口函数
run、dismiss、animate、bind、grid item 等模块级函数。
本页只查 appui 的模块级入口函数和网格辅助函数。页面结构、控件、导航和媒体视图分别看对应 API 参考。
#什么时候用
| 目标 | API |
|---|---|
| 启动 AppUI 页面 | run |
| 关闭当前 AppUI 呈现 | dismiss |
| 包一组状态变化动画 | animate |
| 简单周期刷新 | auto_refresh |
| 降低首次启动延迟 | preload |
| 为值控件创建双向绑定 | bind |
| 声明派生数据 | computed |
| 状态变化后触发副作用 | effect |
| 定义网格列/行 | flexible、fixed、adaptive、grid_item |
| 使用自定义字体 | custom_font |
#最小正确示例
run 只在脚本末尾调用一次。bind 适合 Slider 这类 value + on_change 控件。网格列用 flexible、adaptive 或 fixed。
已复制
import appui
state = appui.State(volume=0.4, selected="Volume")
def select_card(name):
state.selected = name
def card(name, value):
def select_current():
select_card(name)
return (
appui.Button(
action=select_current,
content=appui.VStack([
appui.Text(name).font("caption").foreground_color("secondaryLabel"),
appui.Text(value).font("title3").bold(),
], alignment="leading", spacing=4),
)
.button_style("plain")
.frame(max_width=appui.infinity, min_height=84, alignment="leading")
.padding(12)
.background("secondarySystemBackground", corner_radius=8)
)
@appui.computed(state, depends_on=["volume"])
def volume_text():
return f"{state.volume:.0%}"
def body():
grid = appui.LazyVGrid(
columns=[appui.flexible(minimum=120), appui.flexible(minimum=120)],
spacing=12,
content=[
card("Volume", volume_text()),
card("Selected", state.selected),
],
)
return appui.NavigationStack(
appui.Form([
appui.Section("bind", [
appui.Slider(**appui.bind(state, "volume"), minimum=0, maximum=1),
]),
appui.Section("Grid helpers", [
grid,
]),
]).navigation_title("Functions")
)
appui.run(body, state=state)
#函数签名
| API | 签名 |
|---|---|
run | run(body_func: Optional[Union[Callable[[], View], Callable[[Union[State, ReactiveState, None]], View]]] = None, state: Optional[Union[State, ReactiveState]] = None, hot_reload: bool = False, presentation: str = 'sheet', body: Optional[Union[Callable[[], View], Callable[[Union[State, ReactiveState, None]], View]]] = None) -> None |
dismiss | dismiss() -> None |
presentation_present | presentation_present(field_name: str, *, state: Optional[Union[State, ReactiveState]] = None, value: bool = True) -> bool |
presentation_dismiss | presentation_dismiss(field_name: str, *, state: Optional[Union[State, ReactiveState]] = None) -> bool |
presentation_dismiss_all | presentation_dismiss_all(*, state: Optional[Union[State, ReactiveState]] = None) -> bool |
dismiss_all | dismiss_all(*, state: Optional[Union[State, ReactiveState]] = None) -> bool |
animate | animate(action: Callable[[], None], type: str = 'default') -> None |
auto_refresh | auto_refresh(interval: float = 1.0) -> None |
preload | preload() -> None |
bind | bind(state: Union[State, ReactiveState], field_name: str, *, parse: Optional[Callable[[Any], Any]] = None, format: Optional[Callable[[Any], Any]] = None, validate: Optional[Callable[[Any], bool]] = None) -> Dict[str, Any] |
computed | computed(state: Union[State, ReactiveState], depends_on: Sequence[str]) -> Callable |
effect | effect(state: Union[State, ReactiveState], depends_on: Sequence[str]) -> Callable |
flexible | flexible(minimum: float = 10, maximum: Optional[float] = None) -> Dict[str, Any] |
fixed | fixed(size: float) -> Dict[str, Any] |
adaptive | adaptive(minimum: float = 50, maximum: Optional[float] = None) -> Dict[str, Any] |
grid_item | grid_item(type: str = 'flexible', minimum: Optional[float] = None, maximum: Optional[float] = None, count: Optional[int] = None) -> Dict[str, Any] |
custom_font | custom_font(name: str, size: float = 17) -> str |
#相邻 API 区别
| API | 用法边界 |
|---|---|
bind vs on_change | Slider 这类 value 控件可以用 bind;TextField、Toggle、Picker 通常直接传当前值和 on_change。 |
computed vs 手动字段 | 派生数据用 computed,不要维护第二份 state.filtered_items。 |
effect vs body() 副作用 | 状态变化后的日志或同步用 effect;不要在 body() 里做副作用。 |
auto_refresh vs Timer | 简单原型可用 auto_refresh;正式页面用模块级 Timer 或明确回调。 |
flexible vs adaptive | 固定列数用多个 flexible;根据宽度自动改变列数用 adaptive。 |
#常见错误
| 错误 | 后果 | 修正 |
|---|---|---|
在按钮回调里再次调用 run | 运行时状态混乱 | run 只在脚本末尾调用一次。 |
在 body() 里调用 dismiss() | 页面构建时直接关闭 | 放到按钮或工具栏回调里。 |
把 bind 传给 TextField.text | 参数类型不对 | TextField(text=state.name, on_change=set_name)。 |
用 auto_refresh 做复杂业务轮询 | 刷新不可控 | 使用 Timer、后台任务或明确刷新按钮。 |
| 普通页面绕过公开 API 更新界面 | 可维护性差 | 先查公开 AppUI API。 |