@IT·互联网鸿蒙(HarmonyOS)开发知识

鸿蒙开发实战案例:群头像拼接案例

2025-04-12  本文已影响0人  迪士尼在逃程序员

介绍

本示例介绍使用组件截图实现组件的截图并获取pixelMap对象。该场景多用于通信类应用。

效果图预览

使用说明

  1. 进入群头像案例页面,点击右上角添加图标,在弹出的菜单中点击发起群聊,跳转至发起群聊页面。
  2. 发起群聊页面中,点击下方用户列表前的选择框,选中多个用户,点击右下方完成按钮,添加会话数据。
  3. 在案例首页可以查看新增的会话数据,并可根据选择的用户自行展示群头像。

实现思路

利用组件截图能力获取群头像绘制组件图像。当组件的visibility属性不为None时,均可进行组件截图。

  1. 通过选择的数据,组装群头像布局组件数据。
/**
 * 将选择的头像列表组装为二维数组,用于填充九宫格组件
 * @param images
 * @returns
 */
function divideImage2Group(personGroup: PersonData[]): GroupAvatarModel[][] {
  let imageGroup: GroupAvatarModel[][] = [];
  if (personGroup.length <= 4) {
    // 人数少于等于4时,显示两行两列
    imageGroup = divideGroupBySize(personGroup, 2);
  } else if (personGroup.length <= 9) {
    // 人数大于4时,显示三行三列
    imageGroup = divideGroupBySize(personGroup, 3);
  } else {
    // 人数大于9时,仅显示前9个头像
    imageGroup = divideGroupBySize(personGroup.slice(0, 9), 3);
  }
  return imageGroup;
}

/**
 * 根据群组数量判断排列方式
 *  当群成员人数大于4人,则成员头像为整体区域的1/3,按照九宫格排列
 *  当群成员人数小于等于5人,则成员头像为整体区域的1/2,按照四宫格排列
 * @param images
 * @param rowSize
 * @returns
 */
function divideGroupBySize(personData: PersonData[], rowSize: number): GroupAvatarModel[][] {
  const imageCount: number = personData.length;
  const imageGroup: GroupAvatarModel[][] = [];
  let imageWidth: number = 0;
  let imageHeight: number = 0;
  let rowCount: number = 0;
  let firstRowCount: number = 0;

  // 设置群成员头像大小与排列方式
  if (rowSize === 2) {
    imageWidth = 30;
    imageHeight = 30;
    rowCount = Math.floor(imageCount / 2);
    firstRowCount = imageCount % 2;
  } else if (rowSize === 3) {
    imageWidth = 20;
    imageHeight = 20;
    rowCount = Math.floor(imageCount / 3);
    firstRowCount = imageCount % 3;
  }

  // 组装第一组图片数据
  const firstRowGroup: GroupAvatarModel[] = [];
  for (let i = 0; i < firstRowCount; i++) {
    firstRowGroup.push({
      src: personData[i].headImg,
      width: imageWidth,
      height: imageHeight
    });
  }
  // 当取余为0时,不需要单独设置首行组件
  if (firstRowGroup.length > 0) {
    imageGroup.push(firstRowGroup);
  }

  // 根据排列方式与非首行数,组装剩余的图片数据
  for (let i = 0; i < rowCount; i++) {
    const fullRowImages: PersonData[] =
      personData.slice(firstRowCount + i * rowSize, firstRowCount + (i + 1) * rowSize);
    const fullRowGroup: GroupAvatarModel[] = [];
    fullRowImages.forEach((img: PersonData) => {
      fullRowGroup.push({
        src: img.headImg,
        width: imageWidth,
        height: imageHeight
      });
    });
    imageGroup.push(fullRowGroup);
  }
  return imageGroup;
}
  1. 通过嵌套两层ForEach组件,实现纵向与横向的线性布局。
// 绘制组件,用于绘制群组头像
Column({ space: 2 }) {
  ForEach(divideImage2Group(this.selectPersonGroup), (item: GroupAvatarModel[]) => {
    RowComponent(item)
  })
}
// 设置组件ID,用于进行组件截图
.id('avatar_group')
.width(64)
.height(64)
.justifyContent(FlexAlign.Center)
// 设置组件隐藏
.visibility(Visibility.Hidden)

/**
 * 群组头像横向列表组件
 * @param imageArray
 */
@Builder
function RowComponent(imageArray: GroupAvatarModel[]) {
  Row({ space: 2 }) {
    ForEach(imageArray, (item: GroupAvatarModel) => {
      Image(typeof item.src === 'string' ? $rawfile(item.src) : item.src)
        .height(item.height)
        .width(item.width)
    })
  }
  .width(64)
  .justifyContent(FlexAlign.Center)
}
  1. 使用Stack组件与visibility属性控制组件不显示,设置id属性,用于后续的组件截图操作。
// 使用堆叠组件,实现绘制组件在loading动画后执行
Stack() {
  // 绘制组件,用于绘制群组头像
  Column({ space: 2 }) {
    ForEach(divideImage2Group(this.selectPersonGroup), (item: GroupAvatarModel[]) => {
      RowComponent(item)
    })
  }
  // 设置组件ID,用于进行组件截图
  .id('avatar_group')
  .visibility(Visibility.Hidden)

  // loading弹框
  Column() {
    ...
  }
}
  1. 使用@ohos.arkui.componentSnapshot 接口实现组件截图,并获取群头像资源。
this.getUIContext()
  .getComponentSnapshot()
  .get('avatar_group', (error: Error, pixelMap: image.PixelMap) => {
    ...
  })

高性能知识点

不涉及

工程结构&模块类型

   groupavatar                                     // har类型
   |---datasource
   |   |---DataSource.ets                          // 本地数据 
   |   |---GroupAvatarModel.ets                    // 数据模型
   |---view
   |   |---components
   |   |   |---BottomBarContent.ets                // 底部Tab组件
   |   |   |---CustomLoadingComponent.ets          // loading弹框&群头像绘制组件
   |   |   |---NavigationBarContent.ets            // 顶部导航栏
   |   |   |---PersonContent.ets                   // 用户列表页面
   |   |   |---SessionContent.ets                  // 会话列表页面
   |   |---GroupAvatarAddPage.ets                  // 发起群聊页面
   |   |---GroupAvatarAddPage.ets                  // 首页

写在最后

上一篇 下一篇

猜你喜欢

热点阅读