harmony-chatroom 自研纯血鸿蒙OS Next 5.0聊天APP实战案例

本文涉及的产品
应用实时监控服务-应用监控,每月50GB免费额度
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
可观测监控 Prometheus 版,每月50GB免费额度
简介: HarmonyOS-Chat是一个基于纯血鸿蒙OS Next5.0 API12实战开发的聊天应用程序。这个项目使用了ArkUI和ArkTS技术栈,实现了类似微信的消息UI布局、输入框光标处插入文字、emoji表情图片/GIF动图、图片预览、红包、语音/位置UI、长按语音面板等功能。

历经一个多月潜心研发,重磅原创新作原生鸿蒙harmonyos-chat聊天室项目完成了

未标题-a.png

HarmonyOS-Chat基于纯血鸿蒙OS Next5.0 API12实战开发的聊天应用程序,类似微信的UI界面和功能,提供了包括聊天、通讯录、我、朋友圈等模块。


p1.gif

p2.gif


ArkUI和ArkTS

ArkUI是华为鸿蒙操作系统提供的UI框架,它允许开发者创建丰富的用户界面。ArkTS则是鸿蒙操作系统的一种脚本语言,类似于JavaScript,用于编写ArkUI的应用程序逻辑。


未标题-3.png

p3.gif

arkui实现了下拉刷新、长按菜单,朋友圈等功能。

p3-2.gif

项目结构目录

HarmonyOS-Chat项目的框架结构是基于DevEco Studio 5.0.3.906编码工具构建的。

360截图20241118123651702.png


页面json文件。

df54138f7f1be6d6a7775b64705153d9_1289798-20241119111326298-202389965.png


harmonyos自定义导航条组件

image.png


ffc096406a1fdfa2b1743de6d0217661_1289798-20241119103438252-506834007.png


059e369873a0e442eca9b5de11b3c0b5_1289798-20241031124859083-39238132.png

支持如下参数配置:

@Component
export struct HMNavBar {
  // 是否隐藏左侧的返回键
  @Prop hideBackButton: boolean
  // 标题(支持字符串|自定义组件)
  @BuilderParam title: ResourceStr | CustomBuilder = BuilderFunction
  // 副标题
  @BuilderParam subtitle: ResourceStr | CustomBuilder = BuilderFunction
  // 返回键图标
  @Prop backButtonIcon: Resource | undefined = $r('sys.symbol.chevron_left')
  // 返回键标题
  @Prop backButtonTitle: ResourceStr
  // 背景色
  @Prop bgColor: ResourceColor = $r('sys.color.background_primary')
  // 渐变背景色
  @Prop bgLinearGradient: LinearGradient
  // 图片背景
  @Prop bgImage: ResourceStr | PixelMap
  // 标题颜色
  @Prop fontColor: ResourceColor
  // 标题是否居中
  @Prop centerTitle: boolean
  // 右侧按钮区域
  @BuilderParam actions: Array<ActionMenuItem> | CustomBuilder = BuilderFunction
  // 导航条高度
  @Prop navbarHeight: number = 56

  // ...
}

调用方式:

HMNavBar({
  backButtonIcon: $r('sys.symbol.arrow_left'),
  title: '鸿蒙自定义导航栏',
  subtitle: 'HarmonyOS Next 5.0自定义导航栏',
})
// 自定义渐变背景、背景图片、右侧操作区
HMNavBar({
  hideBackButton: true,
  title: 'HarmonyOS',
  subtitle: 'harmonyos next 5.0 api 12',
  bgLinearGradient: {
    angle: 135,
    colors: [['#42d392 ',0.2], ['#647eff',1]]
  },
  // bgImage: 'pages/assets/nav_bg.png',
  // bgImage: 'https://developer.huawei.com/allianceCmsResource/resource/HUAWEI_Developer_VUE/images/1025-pc-banner.jpeg',
  fontColor: '#fff',
  actions: [
    {
      icon: 'https://developer.huawei.com/allianceCmsResource/resource/HUAWEI_Developer_VUE/images/yuanfuwuicon.png',
      action: () => promptAction.showToast({ message: "show toast index 1" })
    },
    {
      icon: 'https://developer.huawei.com/allianceCmsResource/resource/HUAWEI_Developer_VUE/images/0620logo4.png',
      action: () => promptAction.showToast({ message: "show toast index 2" })
    },
    {
      icon: $r('sys.symbol.person_crop_circle_fill_1'),
      action: () => promptAction.showToast({ message: "show toast index 3" })
    }
  ],
  navbarHeight: 70
})

鸿蒙arkui实现登录/倒计时验证

p0.gif

/**
 * 登录模板
 * @author andy
 */

import { router, promptAction } from '@kit.ArkUI'

@Entry
@Component
struct Login {
  @State name: string = ''
  @State pwd: string = ''

  // 提交
  handleSubmit() {
    if(this.name === '' || this.pwd === '') {
      promptAction.showToast({ message: '账号或密码不能为空' })
    }else {
      // 登录接口逻辑...
      
      promptAction.showToast({ message: '登录成功' })
      setTimeout(() => {
        router.replaceUrl({ url: 'pages/Index' })
      }, 2000)
    }
  }

  build() {
    Column() {
      Column({space: 10}) {
        Image('pages/assets/images/logo.png').height(50).width(50)
        Text('HarmonyOS-Chat').fontSize(18).fontColor('#0a59f7')
      }
      .margin({top: 50})
      Column({space: 15}) {
        TextInput({placeholder: '请输入账号'})
          .onChange((value) => {
            this.name = value
          })
        TextInput({placeholder: '请输入密码'}).type(InputType.Password)
          .onChange((value) => {
            this.pwd = value
          })
        Button('登录').height(45).width('100%')
          .linearGradient({ angle: 135, colors: [['#0a59f7', 0.1], ['#07c160', 1]] })
          .onClick(() => {
            this.handleSubmit()
          })
      }
      .margin({top: 30})
      .width('80%')
      Row({space: 15}) {
        Text('忘记密码').fontSize(14).opacity(0.5)
        Text('注册账号').fontSize(14).opacity(0.5)
          .onClick(() => {
            router.pushUrl({url: 'pages/views/auth/Register'})
          })
      }
      .margin({top: 20})
    }
    .height('100%')
    .width('100%')
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
  }
}

827ca3f17870dd64d47385a5b880e2a7_1289798-20241119113748951-657529179.png

Stack({alignContent: Alignment.End}) {
  TextInput({placeholder: '验证码'})
    .onChange((value) => {
      this.code = value
    })
  Button(`${this.codeText}`).enabled(!this.disabled).controlSize(ControlSize.SMALL).margin({right: 5})
    .onClick(() => {
      this.handleVCode()
    })
}

arkui实现60s倒计时

// 验证码参数
@State codeText: string = '获取验证码'
@State disabled: boolean = false
@State time: number = 60

// 获取验证码
handleVCode() {
  if(this.tel === '') {
    promptAction.showToast({ message: '请输入手机号' })
  }else if(!checkMobile(this.tel)) {
    promptAction.showToast({ message: '手机号格式错误' })
  }else {
    const timer = setInterval(() => {
      if(this.time > 0) {
        this.disabled = true
        this.codeText = `获取验证码(${this.time--})`
      }else {
        clearInterval(timer)
        this.codeText = '获取验证码'
        this.time = 5
        this.disabled = false
      }
    }, 1000)
  }
}

鸿蒙arkui实现下拉刷新/长按菜单

00cf7d864fd4985c00ce2972a2daee85_1289798-20241119115109602-1001433050.png

Refresh({
  refreshing: $$this.isRefreshing,
  builder: this.customRefreshTips
}) {
  List() {
    ForEach(this.queryData, (item: RecordArray) => {
      ListItem() {
        // ...
      }
      .stateStyles({pressed: this.pressedStyles, normal: this.normalStyles})
      .bindContextMenu(this.customCtxMenu, ResponseType.LongPress)
      .onClick(() => {
        // ...
      })
    }, (item: RecordArray) => item.cid.toString())
  }
  .height('100%')
  .width('100%')
  .backgroundColor('#fff')
  .divider({ strokeWidth: 1, color: '#f5f5f5', startMargin: 70, endMargin: 0 })
  .scrollBar(BarState.Off)
}
.pullToRefresh(true)
.refreshOffset(64)
// 当前刷新状态变更时触发回调
.onStateChange((refreshStatus: RefreshStatus) => {
  console.info('Refresh onStatueChange state is ' + refreshStatus)
  this.refreshStatus = refreshStatus
})
// 进入刷新状态时触发回调
.onRefreshing(() => {
  console.log('onRefreshing...')
  setTimeout(() => {
    this.isRefreshing = false
  }, 2000)
})

自定义下拉提示。

@State isRefreshing: boolean = false
@State refreshStatus: number = 1

// 自定义刷新tips
@Builder customRefreshTips() {
  Stack() {
    Row() {
      if(this.refreshStatus == 1) {
        SymbolGlyph($r('sys.symbol.arrow_down')).fontSize(24)
      }else if(this.refreshStatus == 2) {
        SymbolGlyph($r('sys.symbol.arrow_up')).fontSize(24)
      }else if(this.refreshStatus == 3) {
        LoadingProgress().height(24)
      }else if(this.refreshStatus == 4) {
        SymbolGlyph($r('sys.symbol.checkmark')).fontSize(24)
      }
      Text(`${
        this.refreshStatus == 1 ? '下拉刷新' :
          this.refreshStatus == 2 ? '释放更新' :
            this.refreshStatus == 3 ? '加载中...' :
              this.refreshStatus == 4 ? '完成' : ''
      }`).fontSize(16).margin({left:10})
    }
    .alignItems(VerticalAlign.Center)
  }
  .align(Alignment.Center)
  .clip(true)
  .constraintSize({minHeight:32})
  .width('100%')
}

53ed82dfd0d8bc4bdfb0d5f84848ac41_1289798-20241119115230213-1785508169.png

40bf4bafa8a5de2cbd5880f81356e67e_1289798-20241119115302037-837203237.png

Image($r('app.media.plus')).height(24).width(24)
  .bindMenu([
    {
      icon: $r('app.media.message_on_message'),
      value:'发起群聊',
      action: () => {}
    },
    {
      icon: $r('app.media.person_badge_plus'),
      value:'添加朋友',
      action: () => router.pushUrl({url: 'pages/views/friends/AddFriend'})
    },
    {
      icon: $r('app.media.line_viewfinder'),
      value:'扫一扫',
      action: () => {}
    },
    {
      icon: $r('app.media.touched'),
      value:'收付款',
      action: () => {}
    }
  ])

整个项目所涉及知识点非常多,希望以上分享对大家有些帮助~


目录
相关文章
|
21天前
|
安全 数据安全/隐私保护 Android开发
HarmonyOS 5.0 Next实战应用开发—‘我的家乡’【HarmonyOS Next华为公司完全自研的操作系统】
HarmonyOS NEXT是华为自研的鸿蒙操作系统的重要版本更新,标志着鸿蒙系统首次完全脱离Linux内核及安卓开放源代码项目(AOSP),仅支持鸿蒙内核和鸿蒙系统的应用。该版本引入了“和谐美学”设计理念,通过先进的物理渲染引擎还原真实世界的光影色彩,为用户带来沉浸式体验。应用图标设计融合国画理念,采用留白和实时模糊技术展现中式美学。 HarmonyOS NEXT强化了设备间的协同能力,支持无缝切换任务,如在手机、平板或电脑间继续阅读文章或编辑文件。系统注重数据安全和隐私保护,提供数据加密和隐私权限管理功能。此外,它利用分布式技术实现跨设备资源共
101 15
HarmonyOS 5.0 Next实战应用开发—‘我的家乡’【HarmonyOS Next华为公司完全自研的操作系统】
|
21天前
|
存储 JavaScript 开发工具
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
本次的.HarmonyOS Next ,ArkTS语言,HarmonyOS的元服务和DevEco Studio 开发工具,为开发者提供了构建现代化、轻量化、高性能应用的便捷方式。这些技术和工具将帮助开发者更好地适应未来的智能设备和服务提供方式。
56 8
基于HarmonyOS 5.0(NEXT)与SpringCloud架构的跨平台应用开发与服务集成研究【实战】
|
11天前
|
存储 JSON 区块链
【HarmonyOS NEXT开发——ArkTS语言】购物商城的实现【合集】
HarmonyOS应用开发使用@Component装饰器将Home结构体标记为一个组件,意味着它可以在界面构建中被当作一个独立的UI单元来使用,并且按照其内部定义的build方法来渲染具体的界面内容。txt:string定义了一个名为Data的接口,用于规范表示产品数据的结构。src:类型为,推测是用于引用资源(可能是图片资源等)的一种特定类型,用于指定产品对应的图片资源。txt:字符串类型,用于存放产品的文字描述,比如产品名称等相关信息。price:数值类型,用于表示产品的价格信息。
35 5
|
11天前
|
开发工具 开发者 容器
【HarmonyOS NEXT开发——ArkTS语言】欢迎界面(启动加载页)的实现【合集】
从ArkTS代码架构层面而言,@Entry指明入口、@Component助力复用、@Preview便于预览,只是初窥门径,为开发流程带来些许便利。尤其动画回调与Blank组件,细节粗糙,后续定当潜心钻研,力求精进。”,字体颜色为白色,字体大小等设置与之前类似,不过动画配置有所不同,时长为。,不过这里没有看到额外的动画效果添加到这个特定的图片元素上(与前面带动画的元素对比而言)。这是一个显示文本的视图,文本内容为“奇怪的知识”,设置了字体颜色为灰色(的结构体,它代表了整个界面组件的逻辑和视图结构。
32 1
|
22天前
|
人工智能 自然语言处理 API
自学记录HarmonyOS Next的HMS AI API 13:语音合成与语音识别
在完成图像处理项目后,我计划研究HarmonyOS Next API 13中的AI语音技术,包括HMS AI Text-to-Speech和Speech Recognizer。这些API提供了强大的语音合成与识别功能,支持多语言、自定义语速和音调。通过这些API,我将开发一个支持语音输入与输出的“语音助手”原型应用,实现从语音指令解析到语音响应的完整流程。此项目不仅提高了应用的交互性,也为开发者提供了广阔的创新空间。未来,语音技术将在无障碍应用和智慧城市等领域展现巨大潜力。如果你也对语音技术感兴趣,不妨一起探索这个充满无限可能的领域。 (238字符)
89 11
|
24天前
|
存储 API 计算机视觉
自学记录HarmonyOS Next Image API 13:图像处理与传输的开发实践
在完成数字版权管理(DRM)项目后,我决定挑战HarmonyOS Next的图像处理功能,学习Image API和SendableImage API。这两个API支持图像加载、编辑、存储及跨设备发送共享。我计划开发一个简单的图像编辑与发送工具,实现图像裁剪、缩放及跨设备共享功能。通过研究,我深刻体会到HarmonyOS的强大设计,未来这些功能可应用于照片编辑、媒体共享等场景。如果你对图像处理感兴趣,不妨一起探索更多高级特性,共同进步。
73 11
|
20天前
鸿蒙语言开发 几十套鸿蒙ArkTs app毕业设计及课程作业
鸿蒙语言开发 几十套鸿蒙ArkTs app毕业设计及课程作业
28 1
|
2月前
|
安全 Linux 数据安全/隐私保护
Vanilla OS:下一代安全 Linux 发行版
【10月更文挑战第30天】
83 0
Vanilla OS:下一代安全 Linux 发行版
|
11天前
|
弹性计算 自然语言处理 Ubuntu
OS Copilot-操作系统智能助手-Linux新手小白的福音
OS Copilot是由阿里云推出的操作系统智能助手,专为Linux新手设计,支持自然语言问答、辅助命令执行等功能,极大提升了Linux系统的使用效率。用户只需通过简单的命令或自然语言描述问题,OS Copilot即可快速提供解决方案并执行相应操作。例如,查询磁盘使用量等常见任务变得轻松快捷。此外,它还支持从文件读取复杂任务定义,进一步简化了操作流程。虽然在某些模式下可能存在小问题,但总体上大大节省了学习和操作时间,提高了工作效率。
78 2
OS Copilot-操作系统智能助手-Linux新手小白的福音
|
3天前
|
弹性计算 运维 Ubuntu
os-copilot在Alibaba Cloud Linux镜像下的安装与功能测试
我顺利使用了OS Copilot的 -t -f 功能,我的疑惑是在换行的时候就直接进行提问了,每次只能写一个问题,没法连续换行更有逻辑的输入问题。 我认为 -t 管道 功能有用 ,能解决环境问题的连续性操作。 我认为 -f 管道 功能有用 ,可以单独创建可连续性提问的task问题。 我认为 | 对文件直接理解在新的服务器理解有很大的帮助。 此外,我还有建议 可以在非 co 的环境下也能进行连续性的提问。
41 7