/** * 第 3 章配套代码 · 用户卡片页(attr/event/observable 综合演示) * * 文件位置:shared/src/commonMain/kotlin/com/example/kuikly/pages/UserCardPage.kt * * 本示例演示「三件套」的完整用法: * - Pager 页面基类 + observable 状态 * - ViewBuilder 嵌套组件构建 UI 树 * - attr/event 样式属性 vs 交互监听 * * 重点关注: * 1. `val ctx = this` 拿到 Pager 引用,闭包里通过 ctx.xxx 读字段 * 2. attr 里 `if (ctx.liked) Color.RED else Color.GRAY` 演示响应式 * 3. event { click { ... } } 的写法和闭包捕获 */ package com.example.kuikly.pages import com.tencent.kuikly.core.annotations.Page import com.tencent.kuikly.core.base.Color import com.tencent.kuikly.core.base.ViewBuilder import com.tencent.kuikly.core.pager.Pager import com.tencent.kuikly.core.reactive.handler.observable import com.tencent.kuikly.core.views.Image import com.tencent.kuikly.core.views.Text import com.tencent.kuikly.core.views.View @Page("UserCardPage") internal class UserCardPage : Pager() { // ──────────────────────────────────────────────────────── // 响应式状态:observable 委托 // 字段值变化时会自动触发引用了它的 attr 块重新求值 // 详细原理见第 5 章 // ──────────────────────────────────────────────────────── private var liked by observable(false) private var likeCount by observable(128) override fun body(): ViewBuilder { // ★ 关键 1:把 Pager 引用提出来,闭包里通过 ctx.xxx 读 val ctx = this return { // ─── 根容器 ─────────────────────────────── attr { backgroundColor(Color(0xFFF5F5F7L)) padding(20f) } // ─── 用户卡片:白色圆角面板 ──────────────── View { attr { backgroundColor(Color.WHITE) borderRadius(12f) padding(16f) } // ─── 上半部分:头像 + 用户信息 ────── View { attr { flexDirectionRow(); alignItemsCenter() } Image { attr { src("https://example.com/avatar.png") size(48f, 48f) borderRadius(24f) backgroundColor(Color(0xFFE0E0E0L)) // 占位灰 } } View { attr { marginLeft(12f); flex(1f) } Text { attr { text("张三") fontSize(16f) fontWeightBold() color(Color.BLACK) } } Text { attr { text("Kuikly 学习中") fontSize(12f) color(Color(0xFF9E9E9EL)) marginTop(4f) } } } } // ─── 下半部分:操作按钮区 ────────────── View { attr { flexDirectionRow() marginTop(16f) justifyContentSpaceBetween() } // ─── 点赞按钮(响应式 UI 演示)── View { attr { flexDirectionRow() alignItemsCenter() paddingHorizontal(16f) height(36f) borderRadius(18f) // ★ 关键 2:attr 里读 ctx.liked,会被自动追踪为依赖 backgroundColor( if (ctx.liked) Color(0xFFFFEBEEL) else Color(0xFFF5F5F7L) ) } event { // ★ 关键 3:event 闭包捕获 ctx,触发时改字段 click { ctx.liked = !ctx.liked ctx.likeCount += if (ctx.liked) 1 else -1 } } Text { attr { text(if (ctx.liked) "♥" else "♡") color(if (ctx.liked) Color.RED else Color.BLACK) fontSize(16f) } } Text { attr { text("${ctx.likeCount}") marginLeft(6f) fontSize(14f) } } } // ─── 关注按钮 ─────────────────── View { attr { allCenter() paddingHorizontal(16f) height(36f) borderRadius(18f) backgroundColor(Color(0xFF1976D2L)) } event { click { /* TODO 调用关注接口 */ } } Text { attr { text("+ 关注") color(Color.WHITE) fontSize(14f) } } } } } } } }