/** * 第 8 章配套代码 · 平台通信综合 demo * * 文件位置:shared/src/commonMain/kotlin/com/example/kuikly/pages/PlatformBridgeDemo.kt * * 演示 5 个内置 Module 的常用调用方式: * - ToastModule 弹 toast * - StorageModule 本地 KV 存储 * - HttpModule 网络请求 * - PageRouterModule 页面跳转 * - NotificationModule 跨 Pager 广播 */ 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.module.HttpModule import com.tencent.kuikly.core.module.NotificationModule import com.tencent.kuikly.core.module.PageRouterModule import com.tencent.kuikly.core.module.SharedPreferencesModule import com.tencent.kuikly.core.module.ToastModule import com.tencent.kuikly.core.nvi.serialization.json.JSONObject import com.tencent.kuikly.core.pager.Pager import com.tencent.kuikly.core.reactive.handler.observable import com.tencent.kuikly.core.views.Text import com.tencent.kuikly.core.views.View @Page("PlatformBridgeDemo") internal class PlatformBridgeDemo : Pager() { private var fetchResult by observable("(点击下方按钮发起请求)") private var savedToken by observable("") private var loading by observable(false) // ─── 缓存常用 Module 引用 ───── private val toast by lazy { acquireModule(ToastModule.MODULE_NAME) } private val sp by lazy { acquireModule(SharedPreferencesModule.MODULE_NAME) } private val http by lazy { acquireModule(HttpModule.MODULE_NAME) } private val router by lazy { acquireModule(PageRouterModule.MODULE_NAME) } private val notification by lazy { acquireModule(NotificationModule.MODULE_NAME) } // ─── 用 NotificationModule 监听跨页面广播 ───── override fun created() { super.created() savedToken = sp.getItem("auth_token") ?: "" notification.addNotificationListener("UserLoggedIn") { params -> val token = params?.optString("token") ?: "" savedToken = token sp.setItem("auth_token", token) toast.showToast("已收到登录广播:$token") } } override fun pageWillDestroy() { super.pageWillDestroy() // ⚠️ 必须解绑,避免内存泄漏 notification.removeNotificationListener("UserLoggedIn") } override fun body(): ViewBuilder { val ctx = this return { attr { backgroundColor(Color(0xFFF5F5F7L)) paddingTop(40f) paddingHorizontal(16f) } sectionTitle("Platform Bridge 综合演示") // ─── 1. ToastModule ───────────────── actionButton( title = "1. 弹个 Toast (ToastModule)", color = 0xFF1976D2L, onClick = { ctx.toast.showToast("Hello from Kuikly! 🎉") }, ).invoke(this) // ─── 2. StorageModule ─────────────── actionButton( title = "2. 保存 token (StorageModule)", color = 0xFF388E3CL, onClick = { val newToken = "tk_${kotlin.random.Random.nextInt(1000, 9999)}" ctx.sp.setItem("auth_token", newToken) ctx.savedToken = newToken ctx.toast.showToast("已保存:$newToken") }, ).invoke(this) Text { attr { text("当前 token:${ctx.savedToken.ifEmpty { "(无)" }}") fontSize(12f); color(Color(0xFF9E9E9EL)) paddingHorizontal(8f); marginBottom(12f) } } // ─── 3. HttpModule ────────────────── actionButton( title = if (ctx.loading) "3. 请求中…" else "3. 拉一次接口 (HttpModule)", color = 0xFFFF5722L, disabled = ctx.loading, onClick = { ctx.fetchUser() }, ).invoke(this) View { attr { backgroundColor(Color.WHITE) padding(12f) borderRadius(8f) marginBottom(12f) } Text { attr { text(ctx.fetchResult) fontSize(12f); color(Color(0xFF424242L)) lineHeight(18f) } } } // ─── 4. PageRouterModule ──────────── actionButton( title = "4. 跳到 DetailPage (RouterModule)", color = 0xFF7F52FFL, onClick = { ctx.router.openPage( "DetailPage", JSONObject().apply { put("itemId", "abc-${kotlin.random.Random.nextInt(100)}") } ) }, ).invoke(this) // ─── 5. NotificationModule ────────── actionButton( title = "5. 广播 UserLoggedIn 事件", color = 0xFFE91E63L, onClick = { ctx.notification.postNotification( "UserLoggedIn", JSONObject().apply { put("token", "broadcast_${kotlin.random.Random.nextInt(1000)}") } ) }, ).invoke(this) } } // ─── 抽出来的 ViewBuilder ──────────── private fun sectionTitle(title: String): ViewBuilder = { Text { attr { text(title) fontSize(20f) fontWeightBold() color(Color.BLACK) marginBottom(20f) } } } private fun actionButton( title: String, color: Long, disabled: Boolean = false, onClick: () -> Unit, ): ViewBuilder = { View { attr { height(48f) allCenter() backgroundColor(Color(color)) borderRadius(8f) marginBottom(8f) opacity(if (disabled) 0.5f else 1f) } event { click { if (!disabled) onClick() } } Text { attr { text(title) color(Color.WHITE) fontSize(14f) fontWeightBold() } } } } private fun fetchUser() { loading = true fetchResult = "请求中…" http.request( url = "https://jsonplaceholder.typicode.com/users/1", method = "GET", params = JSONObject(), headers = JSONObject(), ) { result -> loading = false if (result == null) { fetchResult = "❌ 请求失败" return@request } val name = result.optString("name", "Unknown") val email = result.optString("email", "") fetchResult = "✅ 收到响应:\n姓名: $name\n邮箱: $email" } } }