HarmonyOS Next 聊天会话详情页开发实践
概述
在 HarmonyOS Next 应用开发中,聊天会话详情页是社交或电商类应用中不可或缺的部分。下面将介绍如何构建一个具备消息展示、发送、图片预览、语音交互等功能的聊天会话详情页。
核心代码功能及对应代码段
1. 页面初始化与数据准备
在页面即将显示时,根据当前断点和导航参数获取当前会话的用户名,并加载对应的消息数据。同时,监听软键盘高度变化事件。
aboutToAppear(): void {
if (this.currentBreakpoint === BreakpointConstants.BREAKPOINT_SM) {
this.currentConversationUserName = String(this.pageInfo.getParamByIndex(0))
} else {
this.currentConversationUserName = String(this.cvsPathInfo.getParamByIndex(0))
}
this.messageInfo = this.currentConversationUserName === '华为官方旗舰店' ? MessageData1 : MessageData2
window.getLastWindow(getContext(this)).then((data => {
data.on('keyboardHeightChange', (data) => {
this.keyBoardHeight = px2vp(data)
if (this.keyBoardHeight > 0) {
this.isAddDlgOpen = false
}
})
}))
}
2. 页面布局与组件构建
使用 NavDestination 和 Stack 进行页面布局,包含顶部搜索栏、消息列表、底部输入框和发送图片按钮等组件。
build() {
NavDestination() {
Stack() {
Flex({ direction: FlexDirection.Column }) {
ConversationDetailTopSearch({ currentConversationUserName: $currentConversationUserName, })
.height(new BreakPointType({
sm: '11%',
md: '11%',
lg: '10%'
}).getValue(this.currentBreakpoint))
.expandSafeArea([SafeAreaType.KEYBOARD], [SafeAreaEdge.BOTTOM])
Scroll() {
Column() {
ForEach(this.messageInfo, (item: MessageDataInterface) => {
ConversationDetailItem({
receivedName: item.name,
isReceived: item.isReceive,
content: item.msg,
type: item.type,
onPreviewImg: this.onPreviewImg.bind(this)
})
})
}
}.expandSafeArea([SafeAreaType.KEYBOARD], [SafeAreaEdge.BOTTOM])
Blank()
ConversationDetailBottom({onSend: this.onSend.bind(this), onOpenAddDlg: this.onOpenAddDlg.bind(this)})
Column() {
Divider()
Row() {
Image($r('app.media.ic_send_image'))
.height(38)
.width(38)
}
.onClick(() => {
AlbumService.selectPicture((result: photoAccessHelper.PhotoSelectResult) => {
this.onSend(result.photoUris[0], 1)
this.isAddDlgOpen = false
this.imageList.push(result.photoUris[0])
})
})
Text('照片')
.fontSize($r('app.float.font_size_twelve'))
.margin({top: 5, left: 32})
.fontColor($r('app.color.font_color_black_two'))
}
.alignItems(HorizontalAlign.Start)
.height(100)
.width('100%')
.visibility(this.isAddDlgOpen ? Visibility.Visible : Visibility.None)
}
.height(StyleConstants.FULL_HEIGHT)
.width(StyleConstants.FULL_WIDTH)
.backgroundColor($r('app.color.background_color_grey'))
.padding({
bottom: deviceInfo.deviceType !== StyleConstants.DEVICE_2IN1 ?
$r('app.float.tab_content_pb') : $r('app.float.zero'), top: AppStorage.get<string>('topAvoid') || 0
})
if (this.isClickImg) {
ImageViewerComponent({
imageList: this.imageList,
active: this.selectIdx,
closePreviewFn: () => {
this.isClickImg = false
}
})
}
if (this.flagUpOpacity === 1) {
Column() {
// 语音交互相关组件
}
}
}
}
.hideTitleBar(true)
}