HarmonyOS鸿蒙Next中设置了List组件的divider属性,item隐藏时分割线仍然显示如何解决

HarmonyOS鸿蒙Next中设置了List组件的divider属性,item隐藏时分割线仍然显示如何解决

【问题现象】

使用List组件,将其中部分item的visibility属性设置为不可见Visibility.None,但是List组件的分隔符依然会显示。

关键代码如下:

private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

List() {
  ForEach(this.arr, (item: number) => {
    ListItem() {
      Row() {
        Text(item.toString())
          .width('100%')
          .fontSize(20)
          .textAlign(TextAlign.Center)
      }.width('100%').visibility(item % 2 == 0 ? Visibility.Visible : Visibility.None)
    }
  }, (item: number) => item.toString())

}.width('100%')
.divider({
  strokeWidth: 0.5,
  color: Color.Red
})

代码效果如下:

点击放大

如图所示,被隐藏的子组件元素所在的区域边缘颜色更深,存在两条分割线(将divider的宽度设置大点,可以更清楚的看到两条分割线合并成的更宽的分割线)。

【背景知识】

List.divider

List组件的divider属性用于设置ListItem分割线样式,默认无分割线。

可以携带一个value参数,设置分割线宽度、颜色和距首尾边缘的距离,用法如下:

divider(value: {strokeWidth: Length; color?: ResourceColor; startMargin?: Length; endMargin?: Length;} | null)

组件通用属性visibility

作用是控制组件是否可见,可带参数:

  • Visibility.Hidden:隐藏,但参与布局进行占位
  • Visibility.Visible:显示
  • Visibility.None:隐藏,但不参与布局,不进行占位

【定位思路】

从渲染效果来看,可以看到是ListItem隐藏了,但是分割线并没有隐藏,也即是元素边框和元素内容的显隐逻辑并不一样,可以通过以下方式处理:

思路1:自定义组件样式

不使用List组件的divider属性,使用自定义Divider,自由控制ListItem 和分割线的显示与隐藏。

思路2:数据预处理

如果觉得自定义样式书写繁琐,比如控制最后一个ListItem下方的分割线隐藏比较麻烦,还有另一种思路:对数据进行预处理,过滤掉隐藏的dataItem。

【解决方式】

自定义组件样式

代码如下:

@Entry
@Component
struct ListDividePage {
  @State dataSource: Array<ListItemModel> = new Array()
  itemNum: number = 9

  aboutToAppear(): void {
    let index = 0;
    while (index < this.itemNum) {
      this.dataSource.push({ "title": index.toString(), "isShow": index % 2 == 0 })
      index++
    }
  }

  build() {
    Column() {
      List() {
        ForEach(this.dataSource, (item: ListItemModel, index: number) => {
          ListItem() {
            Column() {
              if (item.isShow) {
                Row() {
                  Text(item.title)
                    .width('100%')
                    .fontSize(20)
                    .textAlign(TextAlign.Center)
                }
                if (index != this.itemNum - 1) {
                  Divider().strokeWidth(1).color(Color.Red)
                }
              }
            }
          }
        }, (item: ListItemModel) => item.title)
      }
    }
    .width('100%')
  }
}

class ListItemModel {
  constructor() {
  }

  title: string = ""
  isShow: boolean = false
}

数据预处理

代码如下:

@Entry
@Component
struct ListDividePage  {
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] // 后台返回的数据
  @State data: number[] = []; // 筛选出的数据

  aboutToAppear(): void {
    for (let index = 0; index < this.arr.length; index++) {
      if (index % 2 == 0) {
        this.data.push(this.arr[index])
      }
    }
  }

  build() {
    List() {
      ForEach(this.data, (item: number) => {
        ListItem() {
          Row() {
            Text(item.toString())
              .width('100%')
              .fontSize(20)
              .textAlign(TextAlign.Center)
          }.width('100%')
        }
      }, (item: number) => item.toString())

    }.width('100%')
    .divider({
      strokeWidth: 1,
      color: Color.Red
    })
  }
}

正常效果:

点击放大

【总结】

在使用List组件的divider属性时,如果隐藏ListItem后分割线没有隐藏,可以考虑用自定义样式或者改变数据源解决问题。


更多关于HarmonyOS鸿蒙Next中设置了List组件的divider属性,item隐藏时分割线仍然显示如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中设置了List组件的divider属性,item隐藏时分割线仍然显示如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,若设置List组件的divider属性后,隐藏的item仍显示分割线,可以通过以下两种方式解决:

1. 自定义组件样式

不使用List组件的divider属性,改为自定义Divider组件,手动控制分割线的显示与隐藏。具体代码如下:

@Entry
@Component
struct ListDividePage {
  @State dataSource: Array<ListItemModel> = new Array()
  itemNum: number = 9

  aboutToAppear(): void {
    let index = 0;
    while (index < this.itemNum) {
      this.dataSource.push({ "title": index.toString(), "isShow": index % 2 == 0 })
      index++
    }
  }

  build() {
    Column() {
      List() {
        ForEach(this.dataSource, (item: ListItemModel, index: number) => {
          ListItem() {
            Column() {
              if (item.isShow) {
                Row() {
                  Text(item.title)
                    .width('100%')
                    .fontSize(20)
                    .textAlign(TextAlign.Center)
                }
                if (index != this.itemNum - 1) {
                  Divider().strokeWidth(1).color(Color.Red)
                }
              }
            }
          }
        }, (item: ListItemModel) => item.title)
      }
    }
    .width('100%')
  }
}

class ListItemModel {
  constructor() {
  }

  title: string = ""
  isShow: boolean = false
}

2. 数据预处理

在渲染List之前,过滤掉需要隐藏的item数据,确保分割线只显示在可见的item之间。具体代码如下:

@Entry
@Component
struct ListDividePage {
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  @State data: number[] = [];

  aboutToAppear(): void {
    for (let index = 0; index < this.arr.length; index++) {
      if (index % 2 == 0) {
        this.data.push(this.arr[index])
      }
    }
  }

  build() {
    List() {
      ForEach(this.data, (item: number) => {
        ListItem() {
          Row() {
            Text(item.toString())
              .width('100%')
              .fontSize(20)
              .textAlign(TextAlign.Center)
          }.width('100%')
        }
      }, (item: number) => item.toString())

    }.width('100%')
    .divider({
      strokeWidth: 1,
      color: Color.Red
    })
  }
}

通过以上两种方式,可以解决隐藏item后分割线仍然显示的问题。

回到顶部