最新重磅原创鸿蒙版Next5 API12仿微信app界面聊天室|arkts朋友圈
基于
HarmonyOS NEXT5.0
实战仿微信界面聊天App程序HarmonyWeChat。实现编辑器光标处输入文字+emo表情图片、gif动图、图片预览、红包、语音/位置UI、长按语音操作面板等功能。
harmony-chat聊天app包含了聊天、通讯录、我、朋友圈等模块。
版本框架
- DevEco Studio 5.0.0 Release
构建版本:5.0.3.906 - HarmonyOS 5.0.0 Release SDK,基于OpenHarmony SDK Ohos_sdk_public 5.0.0.71 (API Version 12 Release)
- commandline-tools-windows-x64-5.0.3.906
harmonyos arkui自定义弹框、实现微信朋友圈功能。
项目结构目录
使用DevEco Studio 5.0.3.906
编辑器搭建聊天app框架。
HarmonyOS-Chat聊天项目已经更新到我的原创作品集,欢迎下载使用。
HarmonyOS Next5.0 API12 arkts+arkui仿微信app聊天
入口页面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'))
}
鸿蒙os arkts自定义顶部标题栏
HMNavBar组件支持自定义返回键、标题/副标题、标题居中、背景色/背景图片/背景渐变色、标题颜色、搜索、右侧操作区等功能。
之前有分享一篇文章,感兴趣的可以去看看。
https://blog.csdn.net/yanxinyun1990/article/details/143397550
harmonyos实现验证码倒计时
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()
})
}
// 验证码参数
@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)
}
}
鸿蒙next实现下拉刷新/自定义弹框
下拉刷新逻辑
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: () => {}
}
])
鸿蒙os自定义弹窗组件
// 标题(支持字符串|自定义组件)
@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%'
})
harmonyos聊天模块
聊天核心模板
// 聊天模板 Q:282310962
Stack() {
/**
* 聊天主体(消息区/底部操作区)
*/
Column() {
/* 导航条 */
HMNavBar({
title: 'HarmonyOS Next 5.0',
bgLinearGradient: { angle: 135, colors: [['#cc07c160', 0.2], ['#cc0a59f7', 1]] },
fontColor: '#fff',
actions: [
{
icon: $r('sys.symbol.more'),
action: () => router.pushUrl({url: 'pages/views/chat/GroupInfo'})
}
]
})
/* 渲染聊天消息 */
Scroll(this.scroller) {
Column({space: 15}) {
ForEach(this.chatList, (item: ChatArray) => {
// ...
}, (item: ChatArray) => item.id)
}
// 倒叙显示
.reverse(true)
// .padding(15)
.constraintSize({minHeight: '100%'})
.width('100%')
}
// 聊天区翻转
.rotate({angle: 180})
.direction(Direction.Rtl)
.padding(15)
.width('100%')
.layoutWeight(1)
.scrollBar(BarState.On)
.edgeEffect(EdgeEffect.Spring)
.onScrollEdge((side: Edge) => {
if(side === 0) {
console.info('To the bottom edge')
}else if(side === 2) {
console.info('To the top edge')
}
})
.onTouch(() => {
this.handleChatAreaTouched()
})
/* 底部操作栏 */
Row() {
// ....
}
.width('100%')
.backgroundColor('#f8f8f8')
}
.height('100%')
.width('100%')
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
/**
* 录音主体(按住说话)
*/
Column() {
Stack({alignContent: Alignment.Bottom}) {
// ...
}
.height('100%')
.width('100%')
}
.visibility(this.voicePanelEnable ? Visibility.Visible : Visibility.None)
.height('100%')
.width('100%')
.backgroundColor('#99000000')
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
}
.height('100%')
.width('100%')
.backgroundColor($r('sys.color.background_secondary'))
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
聊天消息区,进入页面滚动到聊天底部,采用翻转倒叙方式实现。
/* 底部操作栏 */
Row() {
Column() {
// 输入框模块
Row({space: 10}) {
Row() {
SymbolGlyph($r('sys.symbol.mic_circle')).fontSize(24)
.visibility(this.voiceEnable ? Visibility.None : Visibility.Visible)
SymbolGlyph($r('sys.symbol.keyboard_circle')).fontSize(24)
.visibility(!this.voiceEnable ? Visibility.None : Visibility.Visible)
}
.onClick(() => {
this.voiceEnable = !this.voiceEnable
this.footBarEnable = false
})
Row() {
// 编辑器
RichEditor({controller: this.richEditorController}).backgroundColor('#fff').borderRadius(4).caretColor('#0a59f7')
.visibility(this.voiceEnable ? Visibility.None : Visibility.Visible)
// 按住说话
// 通过item[key]取到值的时候会报错,Indexed access is not supported for fields
// 解决办法Object(item)[key]
Text(`${Object(this.voiceTypeMap)[this.voiceType]}`).backgroundColor('#fff').borderRadius(4).fontSize(15).height(34).width('100%').textAlign(TextAlign.Center)
.visibility(!this.voiceEnable ? Visibility.None : Visibility.Visible)
.onTouch((event: TouchEvent) => {
if(event) {
if(event.type === TouchType.Down) {
this.voiceType = 1
this.voicePanelEnable = true
}
if(event.type === TouchType.Move) {
...
// 触摸判断
if(pos.y >= panY) {
this.voiceType = 1 // 松开发送
}else if(pos.y < panY && pos.x < panX) {
this.voiceType = 2 // 左滑取消发送
}else if(pos.y < panY && pos.x >= panX) {
this.voiceType = 3 // 右滑语音转文字
}
}
if(event.type === TouchType.Up || event.type === TouchType.Cancel) {
switch (this.voiceType) {
...
}
this.voiceType = 0
}
}
})
}
.layoutWeight(1)
SymbolGlyph($r('sys.symbol.capture_smiles')).fontSize(24)
.onClick(() => {
this.handleEmoChooseState(0)
})
SymbolGlyph($r('sys.symbol.plus')).fontSize(24)
.onClick(() => {
this.handleEmoChooseState(1)
})
SymbolGlyph($r('sys.symbol.paperplane')).fontSize(24).fontColor(['#0a59f7'])
.onClick(() => {
this.handleSubmit()
})
}
.padding(10)
.alignItems(VerticalAlign.Center)
// 表情/选择模块
Column() {
if(this.footBarIndex == 0) {
// 表情区域
this.renderEmoWidget()
}else {
// 选择区域
this.renderChooseWidget()
}
}
.height(308)
.width('100%')
.visibility(this.footBarEnable ? Visibility.Visible : Visibility.None)
}
}
.width('100%')
.backgroundColor('#f8f8f8')
整个harmony-chat聊天项目涉及到的知识蛮多的,就暂分享到这里吧。
最后附上几个最新的实战项目,希望能帮助到大家。
-
uniapp+vue3手机版os管理系统
https://blog.csdn.net/yanxinyun1990/article/details/139103578 -
Electron-ViteChat桌面端聊天室|electron31+vite5+pinia2仿微信
https://blog.csdn.net/yanxinyun1990/article/details/140284304 -
vite5-macos仿macOS网页osx管理系统|vue3+arcoDesign桌面os
https://blog.csdn.net/yanxinyun1990/article/details/140701208 -
Electron31-ViteAdmin桌面端后台|vite5.x+electron31+elementPlus后台系统
https://blog.csdn.net/yanxinyun1990/article/details/141310166 -
原创Tauri2.0-Vue3-WinChat客户端聊天Exe程序|tauri2+vite5仿微信
https://blog.csdn.net/yanxinyun1990/article/details/142623032