Kuikly 实战:手把手撸一个跨平台 AI 聊天助手 (ChatDemo)

项目地址:GitHub

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

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

页面结构分析

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

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

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

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

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

kotlin 复制代码
// 伪代码结构演示

Box(modifier = Modifier.fillMaxSize()) {

    Column {

        NavBar() // 1. 天灵盖

        ChatList() // 2. 躯干

        InputArea() // 3. 四肢
    }
}

Kuikly Compose 写法

页面定义

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

kotlin 复制代码
@Page("ChatDemo")

internal class ChatDemo : ComposeContainer() {

    override fun willInit() {

        super.willInit()

        setContent {

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

        }
    }
}

简单粗暴,直接入题!

组件与布局

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

1. 列表组件 (LazyColumn)

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

kotlin 复制代码
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 修饰符:

kotlin 复制代码
TextField(

    modifier = Modifier

    .keyboardHeightChange {

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

        keyboardHeight = it.height
    }

)

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

样式与修饰符 (Modifier)

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

kotlin 复制代码
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 网络库,处理起来行云流水:

kotlin 复制代码
// 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 能力:

kotlin 复制代码
// OhosStreamRequestModule.kt

fun request(...) {

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

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

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

细节打磨:Markdown 渲染

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

kotlin 复制代码
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 下来跑一跑?

相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui