项目地址:GitHub

在这个 AI 大模型满天飞的时代,谁不想拥有一个属于自己的 AI 助手呢?今天,我们就以 ChatDemo 为例,看看如何用一套 Kotlin 代码,在 Android、iOS 和 HarmonyOS 三端上通过 Kuikly Compose 完美复刻 ChatGPT 的流式对话体验。

别被 AI 的高大上吓跑了,其实拆解下来,核心逻辑就像搭积木一样简单。准备好了吗?发车!

页面结构分析

打开 ChatDemo.kt,我们仿佛看到了一位身材曼妙的“美女”——哦不,是一段结构清晰的代码。整个聊天页面 (ChatScreen) 主要由三部分组成:

  1. 顶部导航栏 (NavBar):展示标题和返回按钮,雷打不动的“天灵盖”。

  2. 聊天内容区 (MessageList):显示对话流,这是核心的“躯干”。

  3. 底部输入区 (InputArea):输入框和发送按钮,负责交互的“四肢”。

这种结构在 Kuikly Compose 中实现起来异常清爽,简直就是“所见即所得”:

// 伪代码结构演示

Box(modifier = Modifier.fillMaxSize()) {

    Column {

        NavBar() // 1. 天灵盖

        ChatList() // 2. 躯干

        InputArea() // 3. 四肢
    }
}

Kuikly Compose 写法

页面定义

不同于之前的 BasePager + DSL,Compose 风格的页面继承自 ComposeContainer,通过 setContent 开启 Compose 的世界:


@Page("ChatDemo")

internal class ChatDemo : ComposeContainer() {

    override fun willInit() {

        super.willInit()

        setContent {

            ChatScreen() // 进入 Compose 的声明式 UI 世界

        }
    }
}

简单粗暴,直接入题!

组件与布局

Kuikly Compose 完美复刻了 Jetpack Compose 的开发体验,让习惯了 Android 开发的同学们倍感亲切。

1. 列表组件 (LazyColumn)

聊天记录怎么展示?LazyColumn 也就是我们常说的 RecyclerView 的“升级版”。


LazyColumn(

    state = listState,

    modifier = Modifier.weight(1f)

) {

    itemsIndexed(chatList) { index, message ->

        // 根据 index 判断是用户还是 AI,渲染不同的气泡

        ChatMessageItem(message, isUser = (index % 2 == 0))

    }
}

看到没?没有 Adapter,没有 ViewHolder,就是一个简单的 Lambda,数据驱动 UI,清爽!

2. 输入框 (TextField)

底部的输入框使用了 TextField,这里有一个亮点——键盘避让。Kuikly 贴心地提供了 keyboardHeightChange 修饰符:


TextField(

    modifier = Modifier

    .keyboardHeightChange {

        // 键盘弹起时,自动调整高度,避免遮挡输入框

        keyboardHeight = it.height
    }

)

这行代码一加,键盘弹起时的页面抖动、遮挡问题统统不见,丝般顺滑。

样式与修饰符 (Modifier)

在 Kuikly Compose 中,attr {} 变成了更强大的 Modifier 链式调用。比如首页那个好看的渐变色卡片:


Box(
    modifier = Modifier

    .clip(RoundedCornerShape(16.dp)) // 裁个圆角

    .background(

        // 来个渐变色

        Brush.horizontalGradient(listOf(box.startColor, box.endColor))
    )
    .clickable { ... } // 加个点击事件
)

这就是声明式 UI 的魅力,你要什么效果,直接往上“叠”就行了。

核心黑科技:跨平台流式响应

界面画好了,怎么让 AI “动”起来?ChatDemo 的核心在于流式响应 (SSE),也就是那个酷炫的“打字机”效果。这里展示了 Kuikly 强大的跨平台能力。

Android & iOS (Ktor 协程)

这两兄弟关系好,直接用 Kotlin 协程配合 Ktor 网络库,处理起来行云流水:


// ChatDemo.kt

val channel = response.bodyAsChannel()

while (!channel.isClosedForRead) {

    val line = channel.readUTF8Line()

    if (line.startsWith("data:")) {
        // 收到数据,更新 UI
        withContext(Dispatchers.Main) {
            chatList[msgIndex] += delta // 界面自动刷新
        }
    }
}

HarmonyOS (Native Module 桥接)

鸿蒙这位新朋友,Kuikly 也有妙招。在第三方组件Ktor还未完善对鸿蒙的支持情况下,Kuikly提供了Module 桥接机制,99% 的代码用 KMP 共享,剩下 1% 搞不定的平台特性,通过 Module 轻松桥接原生能力。通过 OhosStreamRequestModule,我们能轻松调用鸿蒙原生的 ArkTS 能力:


// OhosStreamRequestModule.kt

fun request(...) {

    // 呼叫鸿蒙原生层:帮我发个请求!

    toNative(true, "request", params) { retEvent ->
        // 原生层收到 SSE 数据,回传给 Kotlin
        callbackFn.invoke(eventObj)
    }
}

这就是 Kuikly 的哲学:能通用的通用,不能通用的桥接。一套架构,搞定所有平台。

细节打磨:Markdown 渲染

AI 返回的代码块、加粗字体怎么显示?直接塞进 Text 肯定不行。Kuikly 提供了 Markdown 组件:


Markdown(
    state = markdownState,
    colors = markdownColor(text = Color.Black), // 定制颜色
    typography = markdownTypography() // 定制排版
)

它能实时解析流式传输过来的 Markdown 文本,渲染过程毫无闪烁,稳如老狗。

总结

通过 Review ChatDemo 的源码,我们不仅学会了如何画界面,更解锁了 AI 应用开发的核心技能:

  1. Compose 写法:用 Modifier 和声明式组件构建 UI,效率起飞。

  2. 状态管理:mutableState 让数据驱动界面更新,告别繁琐的 setText

  3. 跨平台架构:Ktor 处理标准平台,Module 桥接新兴平台(鸿蒙),游刃有余。

Kuikly 已经把“地基”打好了,剩下的就看你们如何在上面盖出万丈高楼了!今天的代码 Review 就到这里,还不快去 Clone 下来跑一跑?

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐