Cangjie/HarmonyOS-Examples 05-ChatUI聊天界面:消息列表与输入框
还在为鸿蒙应用开发中复杂的聊天界面而头疼吗?本文将深度解析仓颉鸿蒙示例库中的ChatUI项目,带你掌握消息列表与输入框的核心实现技巧,快速构建专业级聊天界面!
读完本文你将获得
- ✅ 完整的聊天界面架构设计思路
- ✅ 消息列表组件的实现原理与最佳实践
- ✅ 输入框与底部工具栏的交互设计
- ✅ 状态管理与数据流的最佳方案
- ✅ 实际可用的代码示例与组件复用技巧
项目概览
ChatUI是仓颉鸿蒙示例库中的第五个示例项目,展示了完整的聊天应用界面实现。该项目包含四个主要界面:
| 界面类型 | 功能描述 | 技术特点 |
|---|---|---|
| 聊天列表 | 显示所有聊天会话 | List组件 + 自定义ListItem |
| 聊天视图 | 消息展示与发送 | Scroll + TextInput + 状态管理 |
| 好友列表 | 联系人管理 | 数据绑定 + 交互逻辑 |
| 动态列表 | 社交动态展示 | 复杂布局 + 图片处理 |
核心组件架构
消息列表组件 (ChatList.cj)
消息列表是整个聊天应用的核心入口,采用分层架构设计:
关键代码实现:
@Component
public class ChatList {
// 聊天项点击的回调
func privateChatOnClick(target: (Chat, User)) {
CURRENT_CHAT.set(target[0])
TARGET_USER.set(target[1])
Router.push(url: "ChatView")
}
let privateChatDataSource = Array<(Chat, User)>([
(chat1, user2), (chat2, user3), (chat3, user4),
(chat4, user5), (chat5, user6), (chat6, user7),
(chat7, user8), (chat8, user9), (chat9, user10)
])
func build() {
Column() {
// 搜索区域
Row() {
Row() {
Image(@r(app.media.search)).size(width: 20, height: 20).margin(right: 10)
Text("搜索").fontSize(16).fontColor(COLOR_GRAY)
}.width(100.percent)
.justifyContent(FlexAlign.Center)
.padding(top: 8, bottom: 8)
.backgroundColor(0xffffff)
.borderRadius(6)
}.width(100.percent)
.padding(left: 20, right: 20)
.margin(bottom: 20)
// 消息列表
List() {
ForEach(privateChatDataSource, itemGeneratorFunc: {elem: (Chat, User), index: Int64 =>
ListItem() {
ChatListItem(
src: elem[1].avatar,
name: elem[1].username,
msg: elem[0].msgs[0].content,
time: elem[0].msgs[0].time,
count: elem[0].count,
bindItem: elem,
onClick: privateChatOnClick
)
}
})
}.padding(left: 20, right: 20, bottom: 50)
.backgroundColor(0xffffff)
}.width(100.percent)
.height(100.percent)
}
}
聊天项组件 (ChatListItem.cj)
聊天项组件采用Builder模式设计,支持高度自定义:
@Builder
public func ChatListItem(
src!: CJResource,
name!: String,
msg!: String,
time!: String,
count!: Int64,
bindItem!: (Chat, User),
onClick!: ((Chat, User)) -> Unit
) {
Row() {
Avatar(src: src, size: 50) // 头像组件
Column() {
// 名称和时间行
Row() {
Text(name).fontSize(18).textOverflow(TextOverflow.Ellipsis)
.maxLines(1).layoutWeight(1)
Text(time).fontSize(12).fontColor(COLOR_SECONDARY)
.width(80).textAlign(TextAlign.End)
}.justifyContent(FlexAlign.Center).alignItems(VerticalAlign.Bottom)
.margin(bottom: 5)
// 消息内容和未读计数行
Row() {
Text(msg).fontSize(14).fontColor(COLOR_SECONDARY)
.textOverflow(TextOverflow.Ellipsis)
.maxLines(1).layoutWeight(1)
MBadge(count: count) // 未读消息徽章
}.justifyContent(FlexAlign.Center).alignItems(VerticalAlign.Center)
}.layoutWeight(1).margin(left: 10)
}.padding(top: 10, bottom: 10)
.margin(top: 5)
.onClick({ e:ClickEvent => onClick(bindItem)})
}
聊天视图实现 (ChatView.cj)
聊天视图是整个应用最复杂的部分,包含消息展示、输入发送、工具栏等功能:
状态管理设计
关键状态变量定义:
@Entry
@Component
public class ChatView {
// 对方用户信息
@State var targetUser: User = user1
// 当前的聊天对象
@State var currentChat: Chat = chat1
// 消息列表
@State var msgList: ArrayList<Message> = ArrayList<Message>([])
// 底部图标大小配置
let bottomIconSize = 30
}
消息渲染逻辑
采用条件渲染区分自己和他人的消息:
// 显示聊天内容的组件
@Builder
func generateChatLine(e: Message, index: Int64) {
if (e.userId == LOCAL_USER.id) {
ChatLine(src: LOCAL_USER.avatar, content: e.content, isSelf: true)
}
else {
ChatLine(src: targetUser.avatar, content: e.content, isSelf: false)
}
}
输入框与工具栏实现
底部输入区域采用灵活的布局设计:
Column(10) {
// 输入框和发送按钮行
Row() {
TextInput()
.fontColor(0x000000)
.backgroundColor(0xffffff)
.layoutWeight(1)
.borderRadius(6.fp)
.margin(right: 10)
Button("发送").shape(ShapeType.Normal)
.height(40)
.width(60)
.fontSize(12)
.fontColor(0xffffff)
.borderRadius(6.fp)
.backgroundColor(Color(67, 151, 247))
}
// 工具栏图标行
Row() {
Image(@r(app.media.microphones)).size(width: bottomIconSize, height: bottomIconSize)
Image(@r(app.media.image)).size(width: bottomIconSize, height: bottomIconSize)
Image(@r(app.media.camera)).size(width: bottomIconSize, height: bottomIconSize)
Image(@r(app.media.red_gift)).size(width: bottomIconSize, height: bottomIconSize)
Image(@r(app.media.emotion_happy_line)).size(width: bottomIconSize, height: bottomIconSize)
Image(@r(app.media.chatview_add_icon))
.size(width: (bottomIconSize - 4), height: (bottomIconSize - 4))
}.width(100.percent)
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.SpaceBetween)
}.padding(left: 10, right: 10, top: 5)
数据模型设计
项目采用清晰的数据结构设计:
| 模型类 | 字段说明 | 用途 |
|---|---|---|
| User | id, username, avatar, status | 用户信息 |
| Chat | id, msgs, count | 聊天会话 |
| Message | id, content, time, userId | 单条消息 |
最佳实践总结
1. 组件化设计
- 将聊天项、消息行等拆分为独立组件
- 使用@Builder装饰器创建可复用组件
- 通过参数传递实现组件定制化
2. 状态管理
- 使用@State管理组件内部状态
- 全局状态通过store统一管理
- 合理使用生命周期函数处理数据初始化
3. 布局技巧
- 灵活使用layoutWeight实现弹性布局
- 通过padding和margin控制间距
- 利用FlexAlign和VerticalAlign对齐元素
4. 交互设计
- 统一的事件处理机制
- 平滑的页面跳转动画
- 直观的反馈效果
常见问题解决方案
Q: 消息列表性能优化
A: 使用ForEach的key参数、避免不必要的重渲染、实现虚拟滚动
Q: 输入框焦点管理
A: 合理设置TextInput的属性和事件处理
Q: 多设备适配
A: 使用响应式布局和尺寸单位适配不同屏幕
通过本文的深度解析,你已经掌握了鸿蒙聊天界面开发的核心技术。ChatUI项目展示了从基础布局到复杂交互的完整实现路径,为你的鸿蒙应用开发提供了宝贵的参考范例。
立即动手实践,打造属于你自己的专业级聊天应用吧!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



