当前位置: 首页 > news >正文

实战教程:启用 Kuikly Compose 从零创建鸿蒙原生计算器

引言:为什么选择 Kuikly Compose 开发鸿蒙应用?

随着鸿蒙生态的快速发展,为这个新平台开发应用已成为许多团队的必选项。然而,学习一门新的语言(ArkTS)和框架(ArkUI)需要成本。如果你是一名 Android 开发者,并且已经熟悉了 Jetpack Compose,那么 Kuikly Compose 让你能够几乎零成本地将 Compose 开发技能直接应用到鸿蒙平台。

本教程将带你一步步使用 Kuikly Compose 开发一个功能完整的计算器应用,并最终运行在鸿蒙设备上。你将亲身体验到 “Write in Kotlin, Run natively on HarmonyOS” 的强大魅力。

一、环境准备与项目创建

1. 前置条件

  • 安装 Android Studio(建议最新版本)
  • 安装 Kuikly Android Studio 插件
  • 配置好鸿蒙开发环境(DevEco Studio,HarmonyOS SDK)
  • 一台鸿蒙真机或模拟器

2. 创建 Kuikly 项目

  1. 在 Android Studio 中,选择 File > New > New Project
  2. 在模板选择中,找到并选择 Kuikly Project Template
  3. 在项目配置向导中,关键一步:在 DSL 选择 处,务必选择 Compose
  4. 填写项目名称(例如 HarmonyCalculator),完成项目创建

项目创建成功后,你的工程会包含以下主要模块:

二、使用 Kuikly Compose 编写计算器界面

我们将在 shared 模块的 commonMain 源码目录下进行开发。Kuikly Compose 的 API 与 Jetpack Compose 高度一致。

1. 创建计算器主页面 (CalculatorApp.kt)

shared/src/commonMain/kotlin/ 下创建文件:

// 导入Kuikly Compose的包,它们与Jetpack Compose的包名非常相似
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.tencent.kuikly.compose.ComposeContainer
import com.tencent.kuikly.core.annotation.Page
// 定义计算器的操作符
sealed class CalculatorAction {
object Clear : CalculatorAction()
object Delete : CalculatorAction()
object Equals : CalculatorAction()
data class Number(val number: Int) : CalculatorAction()
data class Operation(val operation: Char) : CalculatorAction()
}
@Page("Calculator") // 使用@Page注解,这是Kuikly路由系统的关键
class CalculatorApp : ComposeContainer() {
// 使用Compose的状态管理来记录当前输入和计算结果
private var currentInput by mutableStateOf("0")
private var previousInput by mutableStateOf("")
private var currentOperation by mutableStateOf<Char?>(null)override fun willInit() {super.willInit()setContent {// 设置Compose主题和内容MaterialTheme {CalculatorScreen(currentInput = currentInput,previousInput = previousInput,onAction = { handleAction(it) })}}}// 处理计算逻辑private fun handleAction(action: CalculatorAction) {when (action) {is CalculatorAction.Number -> {if (currentInput == "0") {currentInput = action.number.toString()} else {currentInput += action.number.toString()}}is CalculatorAction.Operation -> {if (currentInput.isNotEmpty()) {previousInput = currentInputcurrentInput = "0"currentOperation = action.operation}}CalculatorAction.Equals -> {if (previousInput.isNotEmpty() && currentOperation != null) {val prev = previousInput.toDouble()val current = currentInput.toDouble()val result = when (currentOperation) {'+' -> prev + current'-' -> prev - current'×' -> prev * current'÷' -> if (current != 0.0) prev / current else Double.NaNelse -> return}currentInput = if (result.isNaN()) "Error"else if (result % 1 == 0.0) result.toInt().toString()else result.toString()previousInput = ""currentOperation = null}}CalculatorAction.Clear -> {currentInput = "0"previousInput = ""currentOperation = null}CalculatorAction.Delete -> {if (currentInput.length > 1 && currentInput != "Error") {currentInput = currentInput.dropLast(1)} else {currentInput = "0"}}}}}

2. 构建计算器 UI 组件

// 计算器UI主界面
@Composable
fun CalculatorScreen(
currentInput: String,
previousInput: String,
onAction: (CalculatorAction) -> Unit
) {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFF000000)) // 黑色背景
) {
// 显示屏区域
DisplaySection(
currentInput = currentInput,
previousInput = previousInput,
modifier = Modifier
.weight(2f)
.fillMaxWidth()
)
// 按钮区域
ButtonSection(onAction = onAction, modifier = Modifier.weight(3f))
}
}
// 显示屏组件
@Composable
fun DisplaySection(
currentInput: String,
previousInput: String,
modifier: Modifier = Modifier
) {
Column(
modifier = modifier.padding(16.dp),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.End
) {
// 显示上一次的计算式
Text(
text = previousInput,
color = Color(0xFF888888),
fontSize = 20.sp,
modifier = Modifier.padding(bottom = 8.dp)
)
// 显示当前输入或结果
Text(
text = currentInput,
color = Color.White,
fontSize = 48.sp,
fontWeight = FontWeight.Light,
maxLines = 1
)
}
}
// 按钮区域组件
@Composable
fun ButtonSection(onAction: (CalculatorAction) -> Unit, modifier: Modifier = Modifier) {
val buttonSpacing = 8.dp
Column(modifier = modifier.padding(16.dp)) {
// 第一行: AC, DEL, 空, ÷
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
) {
CalculatorButton(
text = "AC",
color = Color(0xFFA5A5A5),
onClick = { onAction(CalculatorAction.Clear) }
)
CalculatorButton(
text = "DEL",
color = Color(0xFFA5A5A5),
onClick = { onAction(CalculatorAction.Delete) }
)
Spacer(modifier = Modifier.weight(1f))
CalculatorButton(
text = "÷",
color = Color(0xFFFF9500),
onClick = { onAction(CalculatorAction.Operation('÷')) }
)
}
// 第二行: 7, 8, 9, ×
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
) {
CalculatorButton(text = "7", onClick = { onAction(CalculatorAction.Number(7)) })
CalculatorButton(text = "8", onClick = { onAction(CalculatorAction.Number(8)) })
CalculatorButton(text = "9", onClick = { onAction(CalculatorAction.Number(9)) })
CalculatorButton(
text = "×",
color = Color(0xFFFF9500),
onClick = { onAction(CalculatorAction.Operation('×')) }
)
}
// 第三行: 4, 5, 6, -
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
) {
CalculatorButton(text = "4", onClick = { onAction(CalculatorAction.Number(4)) })
CalculatorButton(text = "5", onClick = { onAction(CalculatorAction.Number(5)) })
CalculatorButton(text = "6", onClick = { onAction(CalculatorAction.Number(6)) })
CalculatorButton(
text = "-",
color = Color(0xFFFF9500),
onClick = { onAction(CalculatorAction.Operation('-')) }
)
}
// 第四行: 1, 2, 3, +
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
) {
CalculatorButton(text = "1", onClick = { onAction(CalculatorAction.Number(1)) })
CalculatorButton(text = "2", onClick = { onAction(CalculatorAction.Number(2)) })
CalculatorButton(text = "3", onClick = { onAction(CalculatorAction.Number(3)) })
CalculatorButton(
text = "+",
color = Color(0xFFFF9500),
onClick = { onAction(CalculatorAction.Operation('+')) }
)
}
// 第五行: 0, 空, ., =
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(buttonSpacing)
) {
CalculatorButton(
text = "0",
modifier = Modifier.weight(2f),
onClick = { onAction(CalculatorAction.Number(0)) }
)
CalculatorButton(text = ".", onClick = { /* 小数点功能扩展 */ })
CalculatorButton(
text = "=",
color = Color(0xFFFF9500),
onClick = { onAction(CalculatorAction.Equals) }
)
}
}
}
// 可复用的计算器按钮组件
@Composable
fun CalculatorButton(
text: String,
color: Color = Color(0xFF333333),
modifier: Modifier = Modifier.weight(1f),
onClick: () -> Unit
) {
Box(
contentAlignment = Alignment.Center,
modifier = modifier
.fillMaxSize()
.aspectRatio(1f)
.background(color, shape = androidx.compose.foundation.shape.CircleShape)
.clickable { onClick() }
) {
Text(
text = text,
color = Color.White,
fontSize = 24.sp,
fontWeight = FontWeight.Medium
)
}
}

三、鸿蒙平台适配与运行

代码写完后,我们需要将其编译并运行到鸿蒙设备上。Kuikly 的强大之处在于,你几乎不需要为鸿蒙平台编写任何额外的 UI 代码。

1. 编译 Kotlin 代码为鸿蒙产物

在终端中,进入项目根目录,执行以下命令,将 Kotlin 代码编译成鸿蒙能够调用的 .so 库和头文件:

./gradlew -c settings.ohos.gradle.kts :shared:linkOhosArm64

2. 配置鸿蒙宿主应用 (ohosApp)

Kuikly 项目模板已经生成好了鸿蒙宿主应用的基本配置。确保:

  • ohosApp/entry/oh-package.json5 中的 Kuikly 渲染器版本与 shared/build.gradle.kts 中的版本一致
  • 设备架构配置正确(arm64)

3. 运行鸿蒙应用

  1. 使用 DevEco Studio 打开 ohosApp 目录
  2. 连接鸿蒙设备或启动模拟器
  3. 点击运行按钮,DevEco Studio 会自动安装并启动应用

4. 在鸿蒙设备上体验

应用启动后,你将看到一个标准的计算器界面。这个界面由 Kuikly Compose 代码驱动,但最终渲染的是鸿蒙原生的 ArkUI 组件:

  • 性能流畅:滚动、触摸反馈与纯鸿蒙应用无异
  • 外观原生:字体、布局渲染符合鸿蒙的设计规范
  • 交互自然:所有触摸反馈都符合鸿蒙系统的交互标准

四、核心优势总结

通过这个计算器项目,你可以清晰地感受到 Kuikly Compose 开发鸿蒙应用的优势:

开发效率极高

  • 使用熟悉的 Kotlin 和 Compose DSL
  • 无需学习 ArkTS/ArkUI 新语法
  • 与现有 Android 开发工作流无缝衔接

代码真正复用

⚡ 原生性能保障

  • 最终渲染的是平台原生组件
  • 无性能损耗,体验流畅
  • 直接调用系统底层能力

无缝热更新

下一步探索

你现在已经成功使用 Kuikly Compose 创建了第一个鸿蒙应用!可以在此基础上继续探索:

更复杂的 UI

鸿蒙特定能力

  • 通过 Kuikly 的 Module 机制调用鸿蒙分布式能力
  • 集成传感器、相机等原生 API
  • 实现跨设备协同功能

多端调试

工程化优化

  • 配置 CI/CD 流水线
  • 实现自动化多端构建
  • 集成性能监控和分析工具

Kuikly Compose 为 Kotlin 开发者打开了一扇通往鸿蒙乃至全平台开发的大门,让你能专注于业务逻辑本身,而非纠结于不同平台的技术差异。开始你的跨平台开发之旅吧!

http://www.zskr.cn/news/135196.html

相关文章:

  • 2025年12月实验型立式钟罩冷冻干燥机,环境真空冷冻干燥机,冷冻干燥机厂家推荐:资质与售后全解析 - 品牌鉴赏师
  • 【必学收藏】深入理解RAG核心:搜索技术如何让大模型不再“胡言乱语“?
  • 2025年矿用防爆振动电机直销厂家权威推荐榜单:三段式长杆防爆振动电机/煤安防爆振动电机/粉尘防爆振动电机源头厂家精选 - 品牌推荐官
  • 2025年污水处理聚丙烯酰胺制造厂权威推荐榜单:聚丙烯酰胺乳液/水处理聚丙烯酰胺/聚丙烯酰胺源头厂家精选 - 品牌推荐官
  • 为什么头部外卖平台都在用Open-AutoGLM做出餐提醒?真相曝光
  • 基于51单片机的智能大棚控制器设计
  • 本地商户信息频繁出错?Open-AutoGLM智能修复方案来了,7步搞定数据一致性
  • py每日spider案例之某website壁纸接口
  • 揭秘Open-AutoGLM核心技术:如何实现本地生活服务秒级响应预约?
  • 专业汇智 联通国际:Cylinco Group郭石龙先生获任尼日利亚驻华大使馆特邀证券顾问 - 博客万
  • 2025年靠谱郴州叛逆管教学校排行榜,新测评精选叛逆教育学校推荐 - myqiye
  • LangFlow镜像函数调用节点:嵌入Python脚本灵活处理
  • LangFlow镜像循环结构支持:处理批量数据更高效
  • 【必收藏】2025计算机专业就业真相:8个方向抢人,3个方向烂大街!网络安全方向最吃香
  • 【本地生活服务智能化升级】:基于Open-AutoGLM的5大核心应用场景
  • 计算机毕业设计springboot基于的产品销售数据分析平台设计一广西双迎门业为例 面向门业制造企业的 SpringBoot 产品销售数据洞察与决策支持平台 基于 SpringBoot 的门类产品
  • 基于单片机的中型水族箱环境调节
  • 谷歌AI Agent技术指南深度解读,从概念到生产,企业级智能体的开发与部署方案,附原文下载路径
  • 2025年AI Agent终极预测!迈向自主智能时代,看懂这篇就够了(附年度报告下载)
  • 从下单到配送仅需8秒?揭秘Open-AutoGLM驱动的智能订单路由系统
  • 我惊了!搭建AI知识库居然这么简单?ChatWiki保姆级教程,小白也能从0到1!
  • RAG要变天了!PageIndex框架横空出世,给AI装上“推理大脑”,检索结果精准到离谱!
  • 大模型微调实战指南:从零开始手把手教你微调大模型
  • 彻底颠覆!原来RAG的尽头是“知识图谱”!这套组合拳,让AI问答质量飙升10倍!
  • 电商运维将被取代?Open-AutoGLM实现全天候自动上下架(附实施路线图)
  • 从“飞行相机”到“空中智能体”:无人机如何重构行业生产力
  • 软件CNAS/CMA测评验收机构【Gatling动态参数处理:Session API、EL表达式、随机函数】
  • 基于PLC的船舶生活污水处理系统的仿真与设计
  • LangFlow镜像如何提升AI研发效率?真实数据告诉你
  • 独家解密Open-AutoGLM内部逻辑:如何让系统自主决策订单流转?