HarmonyOS鸿蒙Next中如何实现同一行的ListItem文本高度不一致按最大高度展示

HarmonyOS鸿蒙Next中如何实现同一行的ListItem文本高度不一致按最大高度展示

【问题现象】

在同一行中有多个ListItem时,ListItem中显示的文本高度不一致,导致各ListItem高度不一致,如下图所示:

点击放大

由于文本的长度不确定,无法通过设置height属性来固定ListItem的高度。

【背景知识】

  1. 组件的高度可以通过事件onAreaChange间接获取。当组件区域发生变化时,会触发onAreaChange回调。
  2. 状态变量的状态发生变化时,会触发UI渲染的改变。

【解决方案】

步骤1:计算ListItem高度

计算每个ListItem的高度,并判断同一行中所有ListItem的最大高度。

步骤2:使用状态变量更新布局

使用条件语句if…else和状态变量isBoolean,通过判断状态变量的值的变化,重新对布局进行刷新,并设置每个ListItem的高度为行内的最大高度。

import { JSON } from "@kit.ArkTS"

export class area {
  name: string = ""
  heightSize: number = 0

  constructor(name: string) {
    this.name = name
  }
}

@Entry
@Component
struct Page {
  private arr: area[] =
    [new area('铜梁区'), new area('潼南区'), new area('荣昌区'), new area('开州区'), new area('梁平区'),
      new area('石柱土家族自治县'),
      new area('秀山土家族苗族自治县kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk'),
      new area('酉阳土家族苗族自治县'),
      new area('彭水苗族土家族自治县')]
  private flags: number = 0
  @State private isBoolean: boolean = true

  // 冒泡排序,并取最大值
  sortReturnMax(nums: number[]): number {
    const len: number = nums.length;
    for (let i: number = 0; i < len; i++) {
      for (let j: number = 0; j < len - 1 - i; j++) {
        if (nums[j] > nums[j + 1]) {
          const tmp = nums[j];
          nums[j] = nums[j + 1];
          nums[j + 1] = tmp;
        }
      }
    }
    return nums[nums.length-1]
  }

  // 判断行内高度的最大值,并将arr中的元素的高度设置为高度最大值
  reSetHeightSize() {
    for (let i = 0; i < this.arr.length; i += 3) {
      let arrTmp: number[] = []
      arrTmp.push(this.arr[i].heightSize)
      arrTmp.push(this.arr[i+1].heightSize)
      arrTmp.push(this.arr[i+2].heightSize)

      let maxHeight = this.sortReturnMax(arrTmp)
      this.arr[i].heightSize = maxHeight
      this.arr[i + 1].heightSize = maxHeight
      this.arr[i + 2].heightSize = maxHeight
    }
  }

  // 首次渲染的组件
  @Builder
  ListItemChangeArea() {
    List({ space: 14 }) {
      ForEach(this.arr, (item: area, index: number) => {
        ListItem() {
          TextComponent({ content: item.name })
            .onAreaChange((oldValue: Area, newValue: Area) => {
              // 遍历全部ListItem并收集高度后,调用reSetHeightSize方法计算各行的最大高度,并再完成遍历后改变状态变量isBoolean的值,UI渲染改变
              this.arr[index].heightSize = newValue.height as number
              if (this.flags == this.arr.length - 1) {
                this.isBoolean = false
                this.reSetHeightSize()
              }
              this.flags += 1
            })
        }
      }, (item: area) => JSON.stringify(item))
    }
    .lanes(3)
  }

  // 刷新渲染后的组件
  @Builder
  ListItemSameHeight() {
    List({ space: 14 }) {
      ForEach(this.arr, (item: area, index: number) => {
        ListItem() {
          TextComponent({ content: item.name, hgt: item.heightSize })
        }
      }, (item: area) => JSON.stringify(item))
    }
    .lanes(3)
  }

  build() {
    Column() {
      if (this.isBoolean) {
        // 首次渲染,组件区域变化触发onAreaChange回调,收集并计算ListItem高度
        this.ListItemChangeArea()
      } else {
        // isBoolean值发生改变,进入else语句刷新渲染,此时,各ListItem的高度已是行内的最大高度值
        this.ListItemSameHeight()
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor(0xDCDCDC)
    .padding({ top: 5 })
  }
}

@Component
struct TextComponent {
  content: string = ''
  hgt: Length = 'auto'

  build() {
    Column() {
      Text(this.content)
        .fontSize(14)
        .padding(9)
        .width('100%')
        .textAlign(TextAlign.Center)
    }.height(this.hgt)
    .justifyContent(FlexAlign.Center)
    .border({
      width: 1,
      radius: 7
    })
  }
}

实现效果图:

点击放大

【总结】

通过布局时的组件区域变化,触发onAreaChange回调,获取各组件的高度,通过自定义方法判断和记录行内组件最大高度,并改变状态变量的值触发UI渲染改变,将组件的高度设置为行内组件的最大高度。


更多关于HarmonyOS鸿蒙Next中如何实现同一行的ListItem文本高度不一致按最大高度展示的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中如何实现同一行的ListItem文本高度不一致按最大高度展示的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,实现同一行的ListItem文本高度不一致按最大高度展示的步骤如下:

  1. 计算ListItem高度:使用onAreaChange回调获取每个ListItem的高度,并判断同一行中所有ListItem的最大高度。

  2. 使用状态变量更新布局:通过状态变量isBoolean的变化,触发UI渲染改变。在reSetHeightSize方法中,计算每行的最大高度,并将该行的所有ListItem高度设置为最大高度。

  3. 刷新渲染:根据isBoolean的值,首次渲染时收集并计算高度,刷新渲染时将所有ListItem高度设置为行内最大高度。

最终实现效果为:同一行中的所有ListItem高度一致,且为行内最大高度。

回到顶部