鸿蒙历史搜索功能:tag标签根据文字宽度自动换行 展示更多

一.需求

历史搜索功能,需要根据文字宽度自动换行,并且只展示3行,文字宽度不固定

二.思路

1.通过鸿蒙api MeasureText.measureText 先获取文字宽度

2.通过Row组件的onAreaChange事件监听当前组件高度变化

三.实现

监听需要展示的数量,是否返回完整的数据和需要截取的数量
定义需要用到的变量 如果是v1的话@Local换成@State即可
TypeScript 复制代码
@Local isExpanded: boolean = false // 是否继续计算行高
@Local visibleItemCount: number = 0; // 当前可见的标签数量
@Local arr:string[] = ['123','123','123','123','123','123','123','123']; 
//监听需要展示数量
@Computed
  get displayList() {
    return this.isExpanded
      ? this.arr
      : this.arr.slice(0, this.visibleItemCount);
  }
标签样式和布局样式
TypeScript 复制代码
// 标签样式
  @Builder
  tagView(item: string) {
    Column() {
      Text(item)
        .fontSize(14)
        .fontWeight(400)
        .fontColor('#666666')
        .textOverflow({ overflow: TextOverflow.Ellipsis })
        .maxLines(1)
    }
    .onClick(() => {
      
    })
    .height(32)
    .borderRadius(6)
    .backgroundColor('#F6F7F8')
    .margin({ top: 8, right: 8 })
    .padding({
      left: 12,
      right: 12,
      top: 6,
      bottom: 6
    })
  }

// 布局和监听高度判断
 Column({ space: '8vp' }) {
          Flex({
            direction: FlexDirection.Row, // 横向排列
            wrap: FlexWrap.Wrap, // 自动换行
            justifyContent: FlexAlign.Start, // 左对齐
            alignItems: ItemAlign.Center  // 垂直居中对齐
          }) {
            ForEach(this.displayList), (item: string) => {
              this.tagView(item); // ui样式抽成了Builder,换成自己的就行
            }, (item: string, index: number) => JSON.stringify(item) + index);
            // 展示更多按钮
            if (this.isExpanded) {
              this.moreButton();
            }
          }
         .onAreaChange((oldValue: Area, newValue: Area) => {
            if (this.isExpanded) {
              return; // 已经点击"更多"按钮,直接返回,不再进行计算
            }
            const containerWidth = newValue.width; // 当前页面宽度用来存放标签的总宽度
// 最大高度  这里因为我每行高度是固定40,只展示3行所以是120,可以根据自己需求调整
            const MAX_HEIGHT = 120; 
            if (newValue.height >= MAX_HEIGHT) {
              this.showMoreButton = true; // 显示 "更多" 按钮
              const visibleItemsCount = this.calculateVisibleItems2(Number(containerWidth), MAX_HEIGHT);
              this.visibleItemCount = visibleItemsCount; // 更新当前可见标签数量
            } else {
              this.showMoreButton = false; // 隐藏 "更多" 按钮
              this.visibleItemCount = this.arr.length; // 显示所有标签
            }
          });
        }
高度和宽度计算
TypeScript 复制代码
  //计算显示几个标签 通过行高,最大行数,标签动态宽度
  calculateVisibleItems2(containerWidth: number, maxHeight: number): number {
    const LINE_HEIGHT = 40; // 每行固定高度
    const MAX_LINES = Math.floor(maxHeight / LINE_HEIGHT); // 最大行数
    let currentWidth = 0; // 当前行的宽度累加
    let currentLine = 1; // 当前是第几行
    let visibleCount = 0; // 可见的标签数量
    for (let item of this.vm.searchHistoryList) {
      const itemWidth = this.getTagWidth(item); // 获取标签宽度
      if (currentWidth + itemWidth <= containerWidth) {
        // 标签可以放入当前行
        currentWidth += itemWidth;
      } else {
        // 换行
        currentLine++;
        if (currentLine > MAX_LINES) {
          break; // 超过最大行数,停止计数
        }
        currentWidth = itemWidth; // 新行的第一个标签宽度
      }
      visibleCount++; // 增加可见的标签数量
    }
    return visibleCount;
  }
展示更多按钮
TypeScript 复制代码
@Builder
  moreButton() {
    Column() {
      Text('展示更多')
    }
    .height(32)
    .width(32)
    .backgroundColor('#F6F7F8')
    .borderRadius(6)
    .margin({ top: 8, right: 8 })
    .padding({
      left: 12,
      right: 12,
      top: 6,
      bottom: 6
    })
    .onClick(() => {
     this.isExpanded = true; // 标记为已展开
     this.visibleItemCount = this.arr.length; // 更新为显示所有标签
    })
  }
相关推荐
十九遇你 九十与你25 分钟前
在华为设备上,VRRP与BFD结合使用可以快速检测链路故障并触发主备切换
网络·华为
敢嗣先锋31 分钟前
鸿蒙5.0实战案例:基于OpenGL渲染视频画面帧
移动开发·音视频·harmonyos·arkts·opengl·arkui·鸿蒙开发
桃子酱紫君3 小时前
华为配置篇-OSPF基础实验
华为
BRUCE_WUANG3 小时前
【不是广告】华为昇腾的一小步,Pytorch的一大步
人工智能·pytorch·华为
jian110583 小时前
鸿蒙Android4个脚有脚线
华为·harmonyos·鸿蒙
MardaWang13 小时前
鸿蒙开发中,数据持久化之Transaction(事务)的概念及应用
华为·harmonyos
别说我什么都不会15 小时前
鸿蒙轻内核调测-内存调测-内存信息统计
操作系统·harmonyos
一个处女座的程序猿O(∩_∩)O17 小时前
鸿蒙与DeepSeek深度整合:构建下一代智能操作系统生态
华为·ai·wpf·harmonyos
一只小风华~19 小时前
鸿蒙(HarmonyOS) 自定义弹窗组件
笔记·华为·harmonyos
baobao熊19 小时前
【HarmonyOS Next】自定义Tabs
华为·harmonyos