img

目录

  • 案例介绍
  • 代码实现
  • 代码详解
  • 1. 消息项布局
  • 2. 消息状态显示
  • 3. 滑动操作功能
  • 总结

案例介绍

本篇文章将介绍如何实现消息列表的UI布局和交互功能。我们将实现消息项的布局设计、未读标记、消息状态显示等功能,打造一个交互友好的消息列表界面。

代码实现

@Entry
@Component
struct MessageListExample {
  @Builder
  MessageItemBuilder(message: Message) {
    Row() {
      // 头像占位
      Stack() {
        Column()
          .width(48)
          .height(48)
          .backgroundColor(message.type === MessageType.SYSTEM ? '#0D9FFB' : '#CCCCCC')
          .borderRadius(24)
        
        if (message.isStarred) {
          Column()
            .width(16)
            .height(16)
            .backgroundColor('#FF6B00')
            .borderRadius(8)
            .position({ x: 32, y: 0 })
        }
      }
      .width(48)
      .height(48)
      .margin({ right: 12 })
      
      // 消息内容
      Column() {
        Row() {
          Text(message.senderName)
            .fontSize(16)
            .fontWeight(FontWeight.Medium)
          
          Blank()
          
          Text(message.getFormattedTime())
            .fontSize(12)
            .fontColor('#999999')
        }
        .width('100%')
        .margin({ bottom: 4 })
        
        Row() {
          // 消息类型图标(仅对非文本消息)
          if (message.type !== MessageType.TEXT) {
            Column()
              .width(16)
              .height(16)
              .backgroundColor('#0D9FFB')
              .borderRadius(8)
              .margin({ right: 4 })
          }
          
          Text(message.content)
            .fontSize(14)
            .fontColor(message.isRead ? '#666666' : '#333333')
            .fontWeight(message.isRead ? FontWeight.Normal : FontWeight.Medium)
            .maxLines(1)
            .textOverflow({ overflow: TextOverflow.Ellipsis })
        }
        .width('100%')
      }
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
      
      // 未读标记
      if (!message.isRead) {
        Column()
          .width(8)
          .height(8)
          .backgroundColor('#FF0000')
          .borderRadius(4)
      }
    }
    .width('100%')
    .padding(16)
    .backgroundColor(message.isRead ? '#FFFFFF' : '#F0F7FF')
    .onClick(() => {
      // 标记为已读
      message.isRead = true;
      console.info(`查看消息: ${message.id}`);
    })
  }
  
  @Builder
  SwipeActionButtons(message: Message) {
    Row() {
      Button(message.isRead ? '标为未读' : '已读')
        .width(60)
        .height('100%')
        .backgroundColor('#0D9FFB')
        .fontColor('#FFFFFF')
        .fontSize(12)
        .onClick(() => {
          message.isRead = !message.isRead;
          console.info(`${message.isRead ? '标记为已读' : '标记为未读'}: ${message.id}`);
        })
      
      Button('删除')
        .width(60)
        .height('100%')
        .backgroundColor('#FF0000')
        .fontColor('#FFFFFF')
        .fontSize(12)
        .onClick(() => {
          // 删除消息
          this.messages = this.messages.filter(m => m.id !== message.id);
          // 重新分组
          this.groupMessages();
          console.info(`删除消息: ${message.id}`);
        })
    }
  }
}

代码详解

1. 消息项布局

Row() {
  // 头像部分
  Stack() {
    Column()
      .width(48)
      .height(48)
      .backgroundColor(message.type === MessageType.SYSTEM ? '#0D9FFB' : '#CCCCCC')
      .borderRadius(24)
    
    if (message.isStarred) {
      Column()
        .width(16)
        .height(16)
        .backgroundColor('#FF6B00')
        .borderRadius(8)
        .position({ x: 32, y: 0 })
    }
  }
  
  // 内容部分
  Column() {
    Row() {
      Text(message.senderName)
      Text(message.getFormattedTime())
    }
    
    Row() {
      // 消息类型图标
      if (message.type !== MessageType.TEXT) {
        Column()
          .width(16)
          .height(16)
      }
      
      Text(message.content)
    }
  }
  
  // 未读标记
  if (!message.isRead) {
    Column()
      .width(8)
      .height(8)
  }
}

消息项布局包含三个主要部分:

  1. 头像区域:显示发送者头像,系统消息使用特殊颜色
  2. 内容区域:包含发送者名称、时间、消息内容
  3. 状态标记:显示未读标记和标星标记

2. 消息状态显示

// 未读状态
Text(message.content)
  .fontColor(message.isRead ? '#666666' : '#333333')
  .fontWeight(message.isRead ? FontWeight.Normal : FontWeight.Medium)

// 未读标记
if (!message.isRead) {
  Column()
    .width(8)
    .height(8)
    .backgroundColor('#FF0000')
    .borderRadius(4)
}

// 背景色
.backgroundColor(message.isRead ? '#FFFFFF' : '#F0F7FF')

消息状态的视觉反馈:

  • 未读消息使用深色字体和粗体
  • 显示红点标记
  • 使用特殊背景色

3. 滑动操作功能

@Builder
SwipeActionButtons(message: Message) {
  Row() {
    // 已读/未读切换按钮
    Button(message.isRead ? '标为未读' : '已读')
      .onClick(() => {
        message.isRead = !message.isRead;
      })
    
    // 删除按钮
    Button('删除')
      .onClick(() => {
        this.messages = this.messages.filter(m => m.id !== message.id);
        this.groupMessages();
      })
  }
}

滑动操作功能:

  • 支持标记已读/未读
  • 支持删除消息
  • 操作后自动更新列表

总结

本篇文章展示了如何实现消息列表的UI布局和交互功能。通过合理的组件布局和状态管理,我们实现了消息的展示、状态标记和操作功能。代码实现考虑了不同类型消息的显示需求,并通过视觉设计提供了清晰的状态反馈,打造了一个功能完整、交互友好的消息列表界面。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐