sdk(ui): W_LISTVIEW 虚拟化层 — 固定 item 池 + 多行富 item + 完全自绘 (§5.5)
在既有 W_LISTVIEW (src2 每帧取行) 之上叠加虚拟化层 (API 追加式, 旧 API 一字不改): - 数据源 count_fn + bind_fn (index, meow_lv_item*, ctx); count 每帧实时查 (任意长度≥65535, 不常驻 item 对象); bind 仅在行进入视口时被调一次 - 固定 item 池: 视口行数+2 静态槽 (有界 ≤96), 回滚不重绑 (同 index 命中同槽); 整表扫过后 wrap 回收合法但每次 draw 有界 (≤视口窗口) - 多行富 item: 主标题/副标题/左图标·缩略图/右尾件; 行高 set_item_h(px) 或 set_item_tier(1→48/2→56); 默认 renderer 主题语义色绘制; set_item_draw 完全自绘; section 段头占位行(非粘性); 空态占位 - 集成: tap_at→meow_ui_focus_acquire (§6.4); meow_scroll_wrap(lv,1) track+fling+snap(行边界); 选中/按压态走主题; enabled=0 变淡不响应 - 兼容: src2==NULL 走既有路径; W_LIST/W_LISTVIEW 单行用法零改动 验证(宿主): 新测试 test_meow_ui_listvirt T1-T5 全 44 PASS (10000 项滚动窗口内容正确/hit 映射/ bind 有界=count/回滚不重绑/多行渲染/截断/图标占位/段头/空态/自绘/焦点/fling 吸附); 全量回归 widgets/dispatch/box/anim/scroll/ime/pinyin/overlay/notif/sdk_input_keys/p1p2p3 全 PASS; 交叉 zig-mipsel -Wall -Wextra 全 SDK TU 0 warning; meow_ui.a 新 md5=2a2d8000b95dd211d09dc736d5538ad0 文档: MEOW_APP_SDK.md §5.5 同步虚拟化层(API 一览/池语义/集成/回归).
This commit is contained in:
1 parent
85e1d03157
commit
9d54cf89c5
4 files changed
+797
-69
No files matched your search
+46
-1
@@ -372,7 +372,7 @@ int meow_ui_setform_hit_row(meow_widget *f, int x, int y);/* 命中行号(-1=
|
||||
|
||||
### 5.5 设计模板 A② 列表+选择 [源:2026-08-30]
|
||||
|
||||
> **性质**:SDK 设计模板,供 App 主页/子页按需选用;对既有 `meow_list_create`(B1 最小集,§5,仅 label 文本)做**结构化扩展**(行=图标+标题+副标题+右侧操作 + 选中态)。API「草案/待定案」,不实现。**(✅ 已实现:结构化列表控件 `W_LISTVIEW`,M2.76 · agent-186 · 243148e,见 §5.8.8 分批;长按事件 `MEOW_EV_LONG_PRESS` + `meow_ui_set_long_press_cb/ms`,M2.77 · agent-191 · e95552b。)**
|
||||
> **性质**:SDK 设计模板,供 App 主页/子页按需选用;对既有 `meow_list_create`(B1 最小集,§5,仅 label 文本)做**结构化扩展**(行=图标+标题+副标题+右侧操作 + 选中态)。API「草案/待定案」,不实现。**(✅ 已实现:结构化列表控件 `W_LISTVIEW`,M2.76 · agent-186 · 243148e,见 §5.8.8 分批;长按事件 `MEOW_EV_LONG_PRESS` + `meow_ui_set_long_press_cb/ms`,M2.77 · agent-191 · e95552b;虚拟化层(固定 item 池 + 多行富 item + 完全自绘 + 段头 + 空态),2026-09-02,见 §5.5「虚拟化层」。)**
|
||||
|
||||
**摘要**:可滚动选择容器。**行数据源回调**逐行给出(图标 / 标题 / 副标题 / 右侧操作 / 是否可选),容器负责绘制/滚动/选中/命中;支持**单选、多选、长按**(上下文操作)。适合「已保存网络 / 附近WiFi / 蓝牙设备 / 歌曲列表 / 设置子菜单」等。
|
||||
|
||||
@@ -419,6 +419,51 @@ int meow_ui_listview_hit(meow_widget *lv, int x, int y); /* 命中行;
|
||||
```
|
||||
> 说明:既有 `meow_list_create`(label-only)保留;`meow_ui_listview_*` 为**结构化扩展**(图标/副标题/右侧/选中),可作为真则替换裸 label 列表。
|
||||
|
||||
#### 虚拟化层(2026-09-02,W_LISTVIEW 扩展;API 追加式,旧 API 一字不改)
|
||||
|
||||
> **痛点**:W_LISTVIEW(src2 每帧按需取行)只画可见行,但**每帧重取全部可见行**;大列表(几千/
|
||||
> 上万首)App 只能自行造「滑动窗口」补载(如 ncm playlist.c 的 `pl_maybe_ensure` + `appstate_song_copy`)。
|
||||
> 本层把「固定 item 池 + 多行富 item + 完全自绘」收编为 SDK 级能力,让 App 只提供「总数 + bind」回调。
|
||||
|
||||
**关键交互/数据模型**:
|
||||
- **数据源**:`meow_listview_count_fn`(返回总行数,任意长 ≥65535,不常驻 item 对象)+ `meow_listview_bind_fn`
|
||||
(`index, meow_lv_item*, ctx`,仅在行「进入视口」(绑定到固定池槽)时被调**一次**)。`count` 每帧实时查
|
||||
(搜索过滤/懒加载动态长度)。
|
||||
- **固定 item 池**:池容量 = 视口行数 + 2 静态槽(有界,`MEOW_LV_POOL_MAX`=96),行离开视口不销毁、
|
||||
**回滚不重绑**(同一 index 命中同一槽 → bind 不重调);滚动只改 viewport 偏移(复用既有 set_scroll/max_scroll),
|
||||
不重绑未进视口的项。**整表扫过后池发生 wrap(cap<count),回收合法重绑但每次 draw 有界(≤视口窗口)**。
|
||||
- **多行富 item**:`meow_lv_item` 含 主标题 / 副标题(第二行小字)/ 左图标·缩略图 / 右尾件(chevron·开关·复选·⋯)/
|
||||
`section`(段头占位行)/ `enabled`。行高可配:`set_item_h`(精确 px)或 `set_item_tier(lines)`(1→48 / 2→56)。
|
||||
- **默认 renderer**(`meow_listview_set_item_renderer(lines, show_icon, show_right)`)用主题语义色绘制富 item;
|
||||
**完全自绘**:`meow_listview_set_item_draw(draw_fn, ctx)` 覆盖默认 renderer(App 收 idx/rect/state 自绘整行)。
|
||||
- **段头**:bind 返回 `item->section=1`(title=段名)→ 段头占位行(非粘性;粘性为后续增强)。
|
||||
- **空态**:`meow_listview_set_empty_text(text)`——count==0 时视口内居中画文案。
|
||||
|
||||
**与既有机制集成**:焦点/事件走 §6.4(`meow_listview_tap_at` 命中行自动 `meow_ui_focus_acquire`,点外由
|
||||
`meow_ui_focus_tap` 释放——list 焦点残留根治下沉);滚动接 §12.3 `meow_scroll`(`meow_scroll_wrap(lv, 1)`,
|
||||
`track`+`fling` 跟手/惯性,`set_snap(item_h)` 吸附到行边界);选中/按压态样式走主题
|
||||
(`primaryContainer`/半透明 `primary` 按压层);`enabled=0` 行变淡且命中不响应。
|
||||
|
||||
**API 一览(`include/meow_ui_widgets.h`,§5.5)**:
|
||||
```c
|
||||
typedef struct meow_lv_item { const char *title, *subtitle; const meow_img *icon; int icon_kind;
|
||||
int right, on, enabled, section; void *user; } meow_lv_item;
|
||||
typedef int (*meow_listview_count_fn)(void *ctx);
|
||||
typedef void (*meow_listview_bind_fn)(int index, meow_lv_item *item, void *ctx);
|
||||
typedef void (*meow_listview_draw_fn)(int idx, int x, int y, int w, int h, int state, void *ctx);
|
||||
int meow_listview_set_vsource(meow_widget *lv, meow_listview_count_fn count,
|
||||
meow_listview_bind_fn bind, void *ctx); /* 切 pool 模式 */
|
||||
int meow_listview_set_item_renderer(meow_widget *lv, int lines, int show_icon, int show_right);
|
||||
int meow_listview_set_item_tier(meow_widget *lv, int lines); /* 1→48 / 2→56 */
|
||||
int meow_listview_set_item_draw(meow_widget *lv, meow_listview_draw_fn draw, void *ctx);
|
||||
int meow_listview_set_empty_text(meow_widget *lv, const char *text);
|
||||
```
|
||||
> 兼容:既有 `meow_listview_*`(src2 模式)全部保留不动(`src2==NULL` 走既有路径);本层为叠加。
|
||||
> `meow_widget` 尾部追加虚拟化字段(`calloc` 归零,安全);`meow_ui.a` 需重编,App 链新库(老 ABI 不重建名)。
|
||||
> 宿主验证 `test_meow_ui_listvirt`(T1 虚拟化/bind 有界/回滚、T2 多行/截断/图标/尾件、T3 段头/空态、
|
||||
> T4 自绘、T5 焦点/fling 联动)+ 全量回归 widgets/dispatch/box/anim/scroll/ime/pinyin/overlay/notif/
|
||||
> sdk_input_keys/p1p2p3 全 PASS;交叉 -Wall -Wextra 0 warning。
|
||||
|
||||
---
|
||||
|
||||
### 5.6 设计模板 B③ 弹窗/对话框 [源:2026-08-30]
|
||||
|
||||
Reference in new issue
Block a user