/** * 第 3 章配套代码 · ViewBuilder 抽函数复用 * * 文件位置:shared/src/commonMain/kotlin/com/example/kuikly/pages/ReusableViewBuilder.kt * * 演示如何把通用 UI 块抽成 ViewBuilder 函数,在多个 Pager 里复用。 * * 类比:React 的「函数组件」、Compose 的 `@Composable` 函数 * —— 都是一种让 UI 代码可复用的方式。 * * 关键 API: * - 一个 `() -> ViewBuilder` 函数 = 可参数化的 UI 模板 * - 在 body 里通过 .invoke(this) 应用 ViewBuilder */ 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.views.Image import com.tencent.kuikly.core.views.Text import com.tencent.kuikly.core.views.View // ──────────────────────────────────────────────────────── // 「用户卡片」可复用 ViewBuilder // // 参数化:name、avatar、subtitle 都从外面传入 // 返回值:ViewBuilder(可以被任何 Pager 的 body() 调用) // ──────────────────────────────────────────────────────── fun userCard( name: String, avatar: String, subtitle: String = "", onClick: () -> Unit = {}, ): ViewBuilder = { View { attr { flexDirectionRow() alignItemsCenter() padding(12f) marginBottom(8f) backgroundColor(Color.WHITE) borderRadius(8f) } event { click { onClick() } } Image { attr { src(avatar) size(40f, 40f) borderRadius(20f) backgroundColor(Color(0xFFE0E0E0L)) } } View { attr { marginLeft(12f); flex(1f) } Text { attr { text(name) fontSize(14f) fontWeightBold() color(Color.BLACK) } } if (subtitle.isNotEmpty()) { Text { attr { text(subtitle) fontSize(12f) color(Color(0xFF9E9E9EL)) marginTop(2f) } } } } } } // ──────────────────────────────────────────────────────── // 「分割线」可复用 ViewBuilder(无参数版) // ──────────────────────────────────────────────────────── fun divider(): ViewBuilder = { View { attr { height(0.5f) backgroundColor(Color(0xFFE0E0E0L)) marginVertical(4f) } } } // ──────────────────────────────────────────────────────── // 在 Pager 里组合复用 // ──────────────────────────────────────────────────────── @Page("UserListPage") internal class UserListPage : Pager() { override fun body(): ViewBuilder { return { attr { backgroundColor(Color(0xFFF5F5F7L)) padding(16f) } // ★ 调用方式:调用函数拿到 ViewBuilder,再 invoke 到当前容器 userCard( name = "张三", avatar = "https://example.com/zs.png", subtitle = "Kuikly 学习中", onClick = { /* TODO 跳转到张三主页 */ }, ).invoke(this) userCard( name = "李四", avatar = "https://example.com/ls.png", subtitle = "Compose 死忠", ).invoke(this) divider().invoke(this) userCard( name = "王五", avatar = "https://example.com/ww.png", subtitle = "Flutter 转 Kuikly", ).invoke(this) } } }