自研原生鸿蒙NEXT5.0 API12 ArkTS仿微信app聊天模板HarmonyOSChat

harmony-wechat原创重磅实战纯血鸿蒙OS ArkUI+ArkTs仿微信App聊天实例。包括聊天、通讯录、我、朋友圈等模块,实现类似微信消息UI布局、编辑器光标处输入文字+emo表情图片/GIF动图、图片预览、红包、语音/位置UI、长按语音面板等功能。

版本信息

DevEco Studio 5.0.3.906
HarmonyOS 5.0.0 API12 Release SDK
commandline-tools-windows-x64-5.0.3.906

纯血鸿蒙OS元年已来,华为大力推广自主研发的全场景分布操作系统HarmonyOS,赶快加入鸿蒙原生应用开发,未来可期!

基于鸿蒙os ArkTs 和 ArkUI 实现下拉刷新、右键长按/下拉菜单、自定义弹窗、朋友圈等功能。

项目框架结构

基于最新版 DevEco Studio 5.0.3.906 编码工具构建鸿蒙app聊天项目模板。

https://developer.huawei.com/consumer/cn/deveco-studio/

HarmonyOS-Chat聊天app项目已经发布到我的原创作品集,有需要的可以去拍哈~

https://gf.bilibili.com/item/detail/1107424011

如果大家想快速的入门到进阶开发,先把官方文档撸一遍,然后找个实战项目案例练练手。

华为鸿蒙os开发官网
https://developer.huawei.com/consumer/cn/
HarmonyOS开发设计规范
https://developer.huawei.com/consumer/cn/design/
ArkUI方舟UI框架
https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/arkui-declarative-comp-V5

路由页面JSON文件

HarmonyOS ArkUI自定义顶部导航条

项目中所有顶部标题导航栏均是自定义封装ArkUI组件实现功能效果。之前有写过一篇专门的分享介绍,感兴趣的可以去看看下面这篇文章。

HarmonyOS NEXT 5.0自定义增强版导航栏组件|鸿蒙ArkUI自定义标题栏

https://www.cnblogs.com/xiaoyan2017/p/18517517

Index.ets入口模板

// 自定义页面
@Builder customPage() {
if(this.pageIndex === 0) {
IndexPage()
}else if(this.pageIndex === 1) {
FriendPage()
}else if(this.pageIndex === 2) {
MyPage()
}
} build() {
Navigation() {
this.customPage()
}
.toolbarConfiguration(this.customToolBar)
.height('100%')
.width('100%')
.backgroundColor($r('sys.color.background_secondary'))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
}

// 自定义底部菜单栏
@Builder customToolBar() {
Row() {
Row() {
Badge({
count: 8,
style: {},
position: BadgePosition.RightTop
}) {
Column({space: 2}) {
SymbolGlyph($r('sys.symbol.ellipsis_message_fill'))
Text('聊天').fontSize(12)
}
}
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(() => {
this.pageIndex = 0
}) Row() {
Column({space: 2}) {
SymbolGlyph($r('sys.symbol.person_2'))
Text('通讯录').fontSize(12)
}
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(() => {
this.pageIndex = 1
}) Row() {
Badge({
value: '',
style: { badgeSize: 8, badgeColor: '#fa2a2d' }
}) {
Column({space: 2}) {
SymbolGlyph($r('sys.symbol.person_crop_circle_fill_1'))
Text('我').fontSize(12)
}
}
}
.layoutWeight(1)
.justifyContent(FlexAlign.Center)
.onClick(() => {
this.pageIndex = 2
})
}
.height(56)
.width('100%')
.backgroundColor($r('sys.color.background_secondary'))
.borderWidth({top: 1})
.borderColor($r('sys.color.background_tertiary'))
}

HarmonyOS实现登录/注册/倒计时验证

登录模板

/**
* 登录模板
* @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])
}
}

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()
})
}

鸿蒙arkts实现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)
}
}

鸿蒙os下拉刷新/九宫格图像/长按菜单

  • 下拉刷新组件
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%')
}
  • 长按右键菜单

.bindContextMenu(this.customCtxMenu, ResponseType.LongPress)

// 自定义长按右键菜单
@Builder customCtxMenu() {
Menu() {
MenuItem({
content: '标为已读'
})
MenuItem({
content: '置顶该聊天'
})
MenuItem({
content: '不显示该聊天'
})
MenuItem({
content: '删除'
})
}
}
  • 下拉菜单

.bindMenu([ ... ])

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: () => {}
}
])

HarmonyOS arkui自定义dialog弹框组件

  

  

支持参数配置如下:

// 标题(支持字符串|自定义组件)
@BuilderParam title: ResourceStr | CustomBuilder = BuilderFunction
// 内容(字符串或无状态组件内容)
@BuilderParam message: ResourceStr | CustomBuilder = BuilderFunction
// 响应式组件内容(自定义@Builder组件是@State动态内容)
@BuilderParam content: () => void = BuilderFunction
// 弹窗类型(android | ios | actionSheet)
@Prop type: string
// 是否显示关闭图标
@Prop closable: boolean
// 关闭图标颜色
@Prop closeColor: ResourceColor
// 是否自定义内容
@Prop custom: boolean
// 自定义操作按钮
@BuilderParam buttons: Array<ActionItem> | CustomBuilder = BuilderFunction

调用方式非常简单。

// 自定义退出弹窗
logoutController: CustomDialogController = new CustomDialogController({
builder: HMPopup({
type: 'android',
title: '提示',
message: '确定要退出当前登录吗?',
buttons: [
{
text: '取消',
color: '#999'
},
{
text: '退出',
color: '#fa2a2d',
action: () => {
router.replaceUrl({url: 'pages/views/auth/Login'})
}
}
]
}),
maskColor: '#99000000',
cornerRadius: 12,
width: '75%'
})
// 自定义公众号弹窗
@Builder customQRContent() {
Column({space: 15}) {
Image('pages/assets/images/qrcode.png').height(150).objectFit(ImageFit.Contain)
Text('扫一扫,加我公众号').fontSize(14).opacity(.5)
}
}
qrController: CustomDialogController = new CustomDialogController({
builder: HMPopup({
message: this.customQRContent,
closable: true
}),
cornerRadius: 12,
width: '70%'
})

好了,以上就是harmonyos next实战开发聊天app的一些知识分享,希望对大家有所帮助~

整个项目涉及到的知识点非常多,限于篇幅就先分享到这里。感谢大家的阅读与支持。

https://www.cnblogs.com/xiaoyan2017/p/18396212

https://www.cnblogs.com/xiaoyan2017/p/18437155

https://www.cnblogs.com/xiaoyan2017/p/18467237

HarmonyOS-Chat聊天室|纯血鸿蒙Next5 api12聊天app|ArkUI仿微信的更多相关文章

  1. Websocket直播间聊天室教程 - GoEasy快速实现聊天室

    最近两年直播那个火啊,真的是无法形容!经常有朋友问起,我想实现一个直播间聊天或者我想开发一个聊天室, 要如何开始呢? 今天小编就手把手的教你用GoEasy做一个聊天室,当然也可以用于直播间内的互动.全 ...

  2. 基于nodejs+webSocket的聊天室(实现:加入聊天室、退出聊天室、在线人数、在线列表、发送信息、接收信息)

    1  安装 socket.io模块 npm install "socket.io": "latest" 2 app.js相关 ws = require('soc ...

  3. ASP.NET SignalR 与LayIM配合,轻松实现网站客服聊天室(二) 实现聊天室连接

    上一篇已经简单介绍了layim WebUI即时通讯组件和获取数据的后台方法.现在要讨论的是SingalR的内容,之前都是直接贴代码.那么在贴代码之前先分析一下业务模型,顺便简单讲一下SingalR里的 ...

  4. 利用Node.js的Net模块实现一个命令行多人聊天室

    1.net模块基本API 要使用Node.js的net模块实现一个命令行聊天室,就必须先了解NET模块的API使用.NET模块API分为两大类:Server和Socket类.工厂方法. Server类 ...

  5. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-完整应用例子-在线聊天室系统-下载配置

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  6. python tornado websocket 多聊天室(返回消息给部分连接者)

    python tornado 构建多个聊天室, 多个聊天室之间相互独立, 实现服务器端将消息返回给相应的部分客户端! chatHome.py // 服务器端, 渲染主页 --> 聊天室建立web ...

  7. Java NIO示例:多人网络聊天室

    一个多客户端聊天室,支持多客户端聊天,有如下功能: 功能1: 客户端通过Java NIO连接到服务端,支持多客户端的连接 功能2:客户端初次连接时,服务端提示输入昵称,如果昵称已经有人使用,提示重新输 ...

  8. Linux聊天室项目 -- ChatRome(select实现)

    序 项目简介:采用I/O复用技术select实现socket通信,采用多线程负责每个客户操作处理,完成Linux下的多客户聊天室! OS:Ubuntu 15.04 IDE:vim gcc make D ...

  9. 使用socket.io打造公共聊天室

    最近的计算机网络课上老师开始讲socket,tcp相关的知识,当时脑袋里就蹦出一个想法,那就是打造一个聊天室.实现方式也挺多的,常见的可以用C++或者Java进行socket编程来构建这么一个聊天室. ...

  10. PHP聊天室开源系统workerman-chat

    PHP聊天室开源系统workerman-chat (2015-01-23 09:07:50) 转载▼ http://www.workerman.net/ http://www.workerman.ne ...

随机推荐

  1. 使用 SSH 转义代码来控制连接

    OpenSSH 最常被忽视的一个非常有用的功能是能够从连接内部控制会话的某些方面.通过使用 SSH 转义代码,我们能够在会话内部与本地 SSH 软件进行交互. 强制从客户端断开连接(如何退出卡住或冻结 ...

  2. Chrome 浏览器远程调试 【转】

    Chrome 浏览器按F12,可以调试JS,分析HTTP包等.但是有时候需要远程调试. 比如,某个EXE它内部嵌套了浏览器的话,可以想办法打开它的远程调试功能,然后在外部连到这个地址,就能分析它的ht ...

  3. 全网最适合入门的面向对象编程教程:45 Python 实现常见数据结构-链表、树、哈希表、图和堆

    全网最适合入门的面向对象编程教程:45 Python 实现常见数据结构-链表.树.哈希表.图和堆 摘要: 数据结构是计算机科学中的一种组织和存储数据的方式,它决定了数据的访问方式和操作效率,数据结构的 ...

  4. C++ STL vector 性能之push_back、emplace_back、reserve

    #include <iostream> #include <vector> #include <chrono> using namespace std; const ...

  5. C# 中的 AEAD_AES_256_GCM

    注意:AEAD_AES_256_GCM Key的长度必须是32位,nonce的长度必须是12位,附加数据有可能为空值.AEAD_AES_128_GCM Key的长度必须是16位,nonce的长度必须是 ...

  6. Hadoop & Redis未授权漏洞实战——Vulfocus服务攻防

    什么是未授权访问漏洞?Hadoop & Redis靶场实战--Vulfocus服务攻防 一.介绍 未授权访问,也称为未经授权的访问或非法访问,是指在没有得到适当权限或授权的情况下,个人或系统访 ...

  7. MyBatis——案例——添加

    添加   1.编写接口方法:Mapper接口     参数:除了 id 之外的所有数据     结果:void /** * 添加 */ void add(Brand brand);   2.编写SQL ...

  8. Go 语言中值接收者和指针接收者方法调用的自动转换规则详解

    在 Go 语言中,方法的调用规则对于值接收者和指针接收者有一些特别的行为,这使得代码变得更加简洁和易用.我们来详细解释一下"方法值调用规则"和"方法表达式调用规则&quo ...

  9. 2021年11月墨天轮国产数据库排行榜:openGauss闯入前三,Kingbase流行度与日俱增,TDengine厚积薄发

    2021年11月的国产数据库流行度排行榜已在墨天轮发布,本月共有163家数据库参与排名.就前15名的总体情况来看,除openGauss反超OceanBase闯入前三,TDengine厚积薄发来到第15 ...

  10. 02-react中jsx的基本使用

    // 使用 createElement太繁琐 不直观 不优雅开发体验不好 代码维护不行 // jsx 不是 js 而是 js的扩展语法 // jsx 是react的核心内容 // react项目中已经 ...