news 2026/4/5 5:00:29

【开源鸿蒙跨平台开发--KuiklyUI--03】KuiklyUI 入门实战:从零打造高性能跨平台 Todo 应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【开源鸿蒙跨平台开发--KuiklyUI--03】KuiklyUI 入门实战:从零打造高性能跨平台 Todo 应用

【开源鸿蒙跨平台开发–KuiklyUI–03】KuiklyUI 入门实战:从零打造高性能跨平台 Todo 应用

1. 什么是 KuiklyUI?

KuiklyUI是腾讯开源的一款基于Kotlin Multiplatform (KMP)的高性能跨平台 UI 框架。它的核心理念是“Write Once, Run Everywhere”,但与 Flutter 或 React Native 不同,KuiklyUI 更加强调原生性能轻量级

核心优势

  • 极致性能:核心逻辑编译为 Native 二进制 (Android/iOS/HarmonyOS),UI 渲染直接驱动平台原生组件 (View/UIKit/ArkUI)。
  • 原生体验:拒绝"自绘引擎"带来的非原生手感,KuiklyUI 的组件就是原生组件。
  • 双 DSL 支持:支持自研的简洁 DSL 和 Jetpack Compose 风格 DSL。
  • 全平台覆盖:Android, iOS, HarmonyOS Next, Web (H5), 小程序。

2. 环境准备

在开始之前,请确保你的开发环境满足以下要求:

  • JDK: JDK 17+ (推荐 JDK 17.0.6 或更高)
  • Android 开发: Android Studio Ladybug 或更高版本 (支持 KMP 插件)
  • 鸿蒙开发: DevEco Studio 5.0+ (用于运行鸿蒙宿主工程)
  • 构建工具: Gradle 8.0+ (项目内置,无需手动安装)
  • 操作系统: Windows / macOS / Linux

2.1 鸿蒙环境特别配置

对于鸿蒙开发,你需要配置鸿蒙 SDK 的环境变量,以便 Gradle 能够找到它:

  • Windows: 设置系统环境变量DEVECO_SDK_HOME指向你的 DevEco SDK 路径(例如C:\Users\YourName\AppData\Local\Huawei\Sdk)。
  • macOS: 在~/.bash_profile~/.zshrc中添加export DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk

3. 项目结构概览

克隆项目后,你会看到以下核心目录:

KuiklyUI/ ├── core/ # 框架核心 (KMP) ├── compose/ # Compose DSL 适配层 ├── demo/ # 演示代码 (我们将在这里编写业务逻辑) │ └── src/commonMain/ # 跨平台通用代码 (Write Code Here!) │ ├── kotlin/com/tencent/kuikly/demo/ │ │ ├── pages/ # 页面目录 │ │ ├── widgets/ # 公共组件目录 │ │ └── App.kt # 应用入口 ├── androidApp/ # Android 宿主工程 (仅包含启动代码) ├── ohosApp/ # HarmonyOS 宿主工程 (仅包含启动代码) ├── iosApp/ # iOS 宿主工程 └── 2.0_ohos_demo_build.bat # 鸿蒙编译脚本 (Windows)

开发理念:我们的绝大部分代码(95%以上)都编写在demo/src/commonMain目录下,各个平台的App目录仅作为宿主壳工程,负责加载 Kuikly 引擎。


从AtomGit上下载这个项目KuiklyTodo
解压存放代码的地方查看项目代码,本项目是基于模板项目修改的

4. 实战:开发一个 Todo 应用

我们将实现一个功能完善的待办事项应用,包含:

  1. 待办事项列表展示
  2. 添加新事项
  3. 标记完成/未完成
  4. 删除事项

4.1 定义数据模型

首先,我们需要一个数据类来描述待办事项。在demo/src/commonMain/kotlin/com/tencent/kuikly/demo/pages/todo目录下创建TodoItem.kt

packagecom.tencent.kuikly.demo.pages.tododataclassTodoItem(valid:Long,varcontent:String,varisCompleted:Boolean=false)

4.2 创建页面逻辑类 (ViewModel)

在同目录下创建TodoPage.kt。这是页面的"大脑",负责状态管理和业务逻辑。

/** * @ProjectName : KuiklyUI * @Author : GuoJiaHui * @Time : 2026年01月29日 17:30 PM * @Description : 待办事项页面逻辑控制器 * 负责管理待办事项列表的数据状态、增删改查操作 */packagecom.tencent.kuikly.demo.pages.todoimportcom.tencent.kuikly.core.annotations.Pageimportcom.tencent.kuikly.core.base.ViewBuilderimportcom.tencent.kuikly.demo.pages.base.BasePagerimportcom.tencent.kuikly.core.reactive.handler.observableimportcom.tencent.kuikly.core.reactive.handler.observableList/** * 待办事项页面类 * 使用 @Page 注解标记为页面,路由名称为 "todo_page" */@Page("todo_page")internalclassTodoPage:BasePager(){/** 待办事项列表数据,使用 observableList 实现响应式更新 */vartodoListbyobservableList<TodoItem>()/** 输入框文本状态,使用 observable 实现双向绑定 */varinputTextbyobservable("")/** * 页面创建生命周期回调 * 在此初始化数据 */overridefuncreated(){super.created()// 初始化演示数据initData()}/** * 初始化演示数据 * 添加默认的待办事项 */privatefuninitData(){todoList.add(TodoItem(1,"学习 KuiklyUI 框架"))todoList.add(TodoItem(2,"创建一个 Todo 应用"))}/** * 构建页面 UI 结构 * @return ViewBuilder UI 构建函数 */overridefunbody():ViewBuilder{returnbuildTodoUI(this)}/** 生成 ID 的计数器,起始值为 100 */privatevarnextId=100L/** * 添加新的待办事项 * 校验输入是否为空,创建新项并添加到列表,最后清空输入框 */funaddTodo(){if(inputText.isBlank())returnvalnewItem=TodoItem(nextId++,inputText)todoList.add(newItem)inputText=""}/** * 切换待办事项的完成状态 * @param item 目标待办事项对象 */funtoggleTodo(item:TodoItem){item.isCompleted=!item.isCompleted// 触发列表更新:通过重新赋值触发 observableList 的更新机制valindex=todoList.indexOf(item)if(index>=0){todoList[index]=item}}/** * 删除指定的待办事项 * @param item 要删除的待办事项对象 */fundeleteTodo(item:TodoItem){todoList.remove(item)}/** * 清除所有已完成的待办事项 * 遍历列表并移除 isCompleted 为 true 的项 */funclearCompleted(){todoList.removeAll{it.isCompleted}}}

4.3 编写声明式 UI

创建TodoPageUI.kt,使用 Kuikly 自研 DSL 描述界面。这里的写法类似 Flutter 或 SwiftUI,但完全基于 Kotlin。

/** * @ProjectName : KuiklyUI * @Author : GuoJiaHui * @Time : 2026年01月29日 17:30 PM * @Description : 待办事项页面UI构建逻辑 * 包含整体布局、样式定义及事件绑定 */packagecom.tencent.kuikly.demo.pages.todoimportcom.tencent.kuikly.core.base.Colorimportcom.tencent.kuikly.core.base.ViewBuilderimportcom.tencent.kuikly.core.pager.Pagerimportcom.tencent.kuikly.core.views.*importcom.tencent.kuikly.core.directives.vforimportcom.tencent.kuikly.core.directives.vifimportcom.tencent.kuikly.core.base.Borderimportcom.tencent.kuikly.core.base.BorderStyleimportcom.tencent.kuikly.core.base.BoxShadow/** * 构建 Todo 页面的 UI 结构 * @param page 页面上下文对象,需转换为 TodoPage 类型以访问数据 * @return ViewBuilder UI 构建闭包 */funbuildTodoUI(page:Pager):ViewBuilder{valctx=pageasTodoPagereturn{View{attr{// 设置页面主容器充满全屏flex(1f)backgroundColor(Color.WHITE)// 处理安全区域内边距,适配刘海屏/动态岛padding(top=16f+ctx.pageData.safeAreaInsets.top,left=16f+ctx.pageData.safeAreaInsets.left,right=16f+ctx.pageData.safeAreaInsets.right,bottom=16f+ctx.pageData.safeAreaInsets.bottom)}// 标题栏组件Text{attr{text("待办事项清单")fontSize(24f)fontWeightBold()marginBottom(20f)color(Color.BLACK)}}// 顶部输入区域容器View{attr{flexDirectionRow()// 水平布局marginBottom(20f)height(50f)alignItemsCenter()// 垂直居中}// 文本输入框组件Input{attr{flex(1f)// 占据剩余宽度text(ctx.inputText)// 绑定输入文本placeholder("需要做什么?")fontSize(16f)backgroundColor(Color(0xFFF5F5F5))borderRadius(8f)height(44f)}event{// 监听文本变化事件,更新数据模型textDidChange{params->ctx.inputText=params.text}}}// 添加按钮组件View{attr{width(80f)height(44f)marginLeft(10f)backgroundColor(Color(0xFF007AFF))borderRadius(8f)justifyContentCenter()// 内容居中alignItemsCenter()// 增加按钮投影效果boxShadow(BoxShadow(0f,2f,4f,Color(0x40007AFF)))}Text{attr{text("添加")color(Color.WHITE)fontWeightBold()fontSize(16f)}}event{// 绑定点击事件,调用添加逻辑click{ctx.addTodo()}}}}// 列表显示区域View{attr{flex(1f)// 占据剩余空间}// 空状态提示:当列表为空时显示vif({ctx.todoList.isEmpty()}){View{attr{flex(1f)justifyContentCenter()alignItemsCenter()}Text{attr{text("暂无待办事项")fontSize(18f)color(Color(0xFF999999))marginBottom(8f)}}Text{attr{text("快去添加一个吧!")fontSize(14f)color(Color(0xFFCCCCCC))}}}}// 列表渲染循环:遍历 todoList 生成列表项vfor({ctx.todoList}){item->View{attr{flexDirectionColumn()}// 列表项内容行View{attr{flexDirectionRow()alignItemsCenter()padding(top=12f,bottom=12f)}// 复选框组件(自定义 View 模拟)View{attr{width(24f)height(24f)borderRadius(12f)// 根据完成状态设置边框和背景色border(Border(2f,BorderStyle.SOLID,if(item.isCompleted)Color(0xFF007AFF)elseColor(0xFFCCCCCC)))backgroundColor(if(item.isCompleted)Color(0xFF007AFF)elseColor.TRANSPARENT)marginRight(12f)justifyContentCenter()alignItemsCenter()}event{// 点击复选框切换状态click{ctx.toggleTodo(item)}}// 勾选图标Text{attr{text("✓")color(Color.WHITE)fontSize(14f)fontWeightBold()// 控制勾选标记的透明度opacity(if(item.isCompleted)1felse0f)}}}// 待办事项文本内容Text{attr{text(item.content)fontSize(16f)// 完成状态文字颜色变浅color(if(item.isCompleted)Color(0xFF999999)elseColor(0xFF333333))flex(1f)// 完成状态添加删除线if(item.isCompleted)textDecorationLineThrough()else"textDecoration"with"none"}event{// 点击文字也可切换状态click{ctx.toggleTodo(item)}}}// 删除按钮View{attr{padding(8f)// 增加点击热区}event{click{ctx.deleteTodo(item)}}Text{attr{text("✕")color(Color(0xFFFF3B30))// 红色警示色fontSize(18f)}}}}// 分割线View{attr{height(1f)backgroundColor(Color(0xFFEEEEEE))marginLeft(36f)// 缩进以对齐文本}}}}}// 底部状态栏与操作区(仅当列表不为空时显示)vif({ctx.todoList.isNotEmpty()}){View{attr{flexDirectionColumn()}// 顶部分割线View{attr{height(1f)backgroundColor(Color(0xFFEEEEEE))}}// 底部内容容器View{attr{flexDirectionRow()justifyContentSpaceBetween()// 两端对齐alignItemsCenter()padding(top=16f)}// 剩余待办计数Text{attr{text("${ctx.todoList.count{!it.isCompleted}}项待办")fontSize(14f)color(Color(0xFF666666))}}// 清除已完成按钮View{attr{padding(8f)}event{click{ctx.clearCompleted()}}Text{attr{text("清除已完成")fontSize(14f)color(Color(0xFF007AFF))}}}}}}}}}

5. 跨端运行指南

5.1 Android 运行

Android 是最简单的运行平台。

  1. 打开 Android Studio。
  2. 等待 Gradle Sync 完成。
  3. 在运行配置下拉菜单中选择androidApp
  4. 点击运行按钮 (Run)。

修改完代码后要先重新构建

构建完成后点击最上面的运行
安卓运行效果

提示:如果遇到 KMP 相关的配置错误,请确保你的 Android Studio 安装了 Kotlin Multiplatform Mobile 插件。

5.2 HarmonyOS 运行

鸿蒙的运行流程涉及 Native 库的交叉编译,需要特别注意。

步骤 1:编译 Native 库

KuiklyUI 的核心逻辑需要编译成鸿蒙系统的动态链接库 (.so)。

  1. 找到项目根目录下的2.0_ohos_demo_build.bat文件。
  2. 双击运行,或者在终端中执行:
    .\2.0_ohos_demo_build.bat
  3. 脚本会自动执行 Gradle 任务,编译生成libshared.so并复制到ohosApp/entry/libs/arm64-v8a/目录下。

    注意:如果脚本报错找不到 SDK,请检查章节 2.1 中的环境变量配置。

步骤 2:配置 DevEco Studio
  1. 启动 DevEco Studio。
  2. 选择Open Project,打开项目中的ohosApp目录。
  3. 等待 Sync 完成。
步骤 3:实现 Native Bridge (可选但推荐)

如果你的应用需要跳转页面或调用原生能力,需要配置 Bridge。
打开ohosApp/entry/src/main/ets/kuikly/modules/KRBridgeModule.ets,完善openPage方法:

// KRBridgeModule.etsimportrouterfrom'@ohos.router';// ...// TODO open new pageprivateopenPage(params:KRAny){console.info('KRBridgeModule: openPage method execution started');try{letargs:Record<string,Object>;if(typeofparams==='string'){args=JSON.parse(params)asRecord<string,Object>;}else{args=paramsasRecord<string,Object>;}consturl=args['url']asstring;// 使用鸿蒙原生路由跳转router.pushUrl({url:'pages/Index',params:{pageName:url// 将目标页面名传给 Index 页面}});}catch(e){console.error(`KRBridgeModule: openPage error:${JSON.stringify(e)}`);}}
步骤 4:真机运行

由于 Kuikly 编译的是 ARM64 架构的.so库,不支持 x86 模拟器

  1. 连接你的鸿蒙真机 (Mate 60 / Pura 70 等)。

  2. 或者申请华为云真机(参考我们另一篇云真机部署教程)。

  3. 点击 DevEco Studio 的运行按钮。

    真机运行效果


6. 调试技巧与常见问题

6.1 如何查看日志?

  • Android: 使用 Logcat,过滤KuiklySystem.out
  • HarmonyOS: 使用 DevEco Studio 的 Log 面板,过滤HiLog,关键字KuiklyKRBridgeModule
    • 在 Kotlin 代码中可以使用KLog.i("Tag", "Message")打日志。

6.2 常见编译错误

  • Unresolved reference: System:
    • 原因: Kotlin/Native (鸿蒙/iOS) 中没有 Java 的System类。
    • 解决: 使用Clock.System.now()(需要 kotlinx-datetime) 或者简单的自增 ID (如本教程所示)。
  • settings.2.0.ohos.gradle.kts does not exist:
    • 原因: 缺少鸿蒙专用构建配置。
    • 解决: 运行.bat脚本前确保该文件存在 (脚本通常会自动处理或依赖项目预设)。

7. 总结

通过这个实战,我们不仅完成了一个 Todo 应用,还深入理解了:

  1. MVI 架构雏形:State (状态) -> UI (视图) -> Event (事件) 的单向数据流。
  2. DSL 布局:如何用 Kotlin 代码构建复杂的 Flexbox 布局。
  3. 多端适配:如何通过一套代码,在 Android 和 HarmonyOS 上运行原生的 UI。

KuiklyUI让跨平台开发不再是 WebView 的妥协,而是原生性能的释放。快去尝试构建更复杂的应用吧!

8. 延伸阅读

  • 【开源鸿蒙跨平台开发–KuiklyUI】 Windows平台Kuikly OpenHarmony开发环境搭建及脚本编译模板工程流程
  • Kuikly官方文档
  • OpenHarmony官方文档
  • Kotlin Multiplatform官方文档

欢迎加入开源鸿蒙跨平台社区:开源鸿蒙跨平台开发者社区

版权声明:本文遵循 CC 4.0 BY-SA 协议,转载请注明出处。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/17 23:31:31

天津商业空间设计:本地团队的美学落地方案 [特殊字符]

天津商业空间设计&#xff1a;本地团队的美学落地方案 &#x1f3a8;天津作为北方商业枢纽&#xff0c;从老租界的洋楼商圈到滨海的新商业体&#xff0c;商业空间的迭代一直是品牌破局的关键。但不少品牌踩过坑&#xff1a;外地设计团队照搬网红模板&#xff0c;结果和天津消费…

作者头像 李华
网站建设 2026/3/31 21:32:41

Java Web web大学生一体化服务平台系统源码-SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0【含文档】

摘要 随着信息技术的快速发展&#xff0c;高校管理服务模式正逐步向数字化、智能化转型。传统的高校学生服务平台往往存在功能单一、数据孤岛、用户体验差等问题&#xff0c;难以满足现代大学生多元化、个性化的需求。为解决这些问题&#xff0c;本研究设计并实现了一款基于Jav…

作者头像 李华
网站建设 2026/4/1 8:47:15

基于springboot + vue员工信息管理系统(源码+数据库+文档)

员工信息管理 目录 基于springboot vue网上订餐系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于springboot vue员工信息管理系统 一、前言 博主介绍&#xff…

作者头像 李华
网站建设 2026/3/31 18:01:10

depcheck 依赖检测

depcheck是Node.js 项目专属的依赖检测工具&#xff0c;核心作用是静态分析项目代码与package.json&#xff0c;自动找出未使用、缺失、冗余的依赖&#xff0c;解决项目迭代中依赖臃肿&#xff08;装了没用&#xff09;、漏装依赖&#xff08;代码用了但没在package.json声明&a…

作者头像 李华
网站建设 2026/4/5 1:41:24

环境艺术设计 AI+虚拟仿真 实训室:破解教学痛点,赋能智慧教学

职业院校环境艺术设计专业作为连接创意设计与产业落地的核心教育载体&#xff0c;其教学质量直接决定了人才供给与行业需求的适配度。然而在传统教学模式下&#xff0c;教师面临着实训成本高、教学效果难验证、技术教学脱节等多重困境&#xff0c;严重影响了人才培养质量。恒点…

作者头像 李华