HarmonyOS 鸿蒙Next中List中设置divider显示异常

HarmonyOS 鸿蒙Next中List中设置divider显示异常 cke_377.png

相关代码

List() {
 Repeat<SetInfoItem>(this.setInfoItemlist)
    .each((reItem)=>{
      ListItem() {
        this.setItemInfo(reItem.item)
      }.width('100%')
    })
  
}
.width('100%')
.divider({
  color:Color.Red,
  strokeWidth :1,
  startMargin :10,
  endMargin:10

})
.edgeEffect(EdgeEffect.Spring)

官方给的使用方法:

cke_1807.png

为了方便给老师排查问题, 我把一些无关因素都去掉了, 然后附上最简洁的代码

build() {

  HdsNavDestination() {
    AppTitleBar(this.pageContext, "设置");
    List() {
      ListItem(){
        Text("         测试1")
          .width('100%')
          .height(50)
      }
      ListItem(){
        Text("          测试2")
          .width('100%')
          .height(50)
      }
      ListItem(){
        Text("          测试3")
          .width('100%')
          .height(50)
      }
    }
    .divider({
      color:Color.Red,
      strokeWidth :1,
    })
    .width('100%')
    .layoutWeight(1)

    Button("退出登录")
      .width("80%")
      .height(40)
      .onClick(() => {
        this.dialogController.open()
      })

  }
  .width('100%')
  .height('100%')
  .hideTitleBar(true)
  .backgroundColor("#F5F5F5")

}

然后模拟器上的效果, 分割线就彻底乱了

cke_18034.png


更多关于HarmonyOS 鸿蒙Next中List中设置divider显示异常的实战教程也可以访问 https://www.itying.com/category-93-b0.html

11 回复

开发者你好,目前使用divider显示时符合官网示例预期的;

你这边的问题是:“一寸免冠照片”和“修改登录密码”之间没有分割线吗?麻烦你这边描述一下具体的问题点,提供一下您这边的最小化demo。

@Entry
@ComponentV2
struct NestedRepeat {
  @Local outerList: string[] = [];
  @Local innerList: number[] = [];

  aboutToAppear(): void {
    for (let i = 0; i < 20; i++) {
      this.outerList.push(i.toString());
      this.innerList.push(i);
    }
  }

  build() {
    Column({ space: 20 }) {
      Text('Nested Repeat with virtualScroll')
        .fontSize(15)
        .fontColor(Color.Gray)
      List() {
        Repeat<string>(this.outerList)
          .each((obj) => {
            ListItem() {
              Column() {
                Text('outerList item: ' + obj.item)
                  .fontSize(30)
              }
              .height('10%')
              .backgroundColor(Color.Pink)
            }
            // .border({ width: 1 })
          })
          .key((item) => 'outerList_' + item)
          .virtualScroll()
      }
      .divider({
        color:Color.Red,
        strokeWidth :1,
        // startMargin :10,
        // endMargin:10
      })
      .width('80%')
      // .border({ width: 1 })
    }
    .justifyContent(FlexAlign.Center)
    .width('90%')
    .height('80%')
  }
}

更多关于HarmonyOS 鸿蒙Next中List中设置divider显示异常的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


对, 是第一个item没有下划线, 最后一个item还多出来了一条,感觉是下划线高度计算失误的. 我精简了下代码, 重新编辑了问题, 方便老师排查,

开发者你好,当前根据你提供的demo,当前使用API21版本IDE以及对应21版本模拟器,是可以正常显示的;可能是模拟器版本低了,可以官网下载最新开发工具以及模拟器再试下:https://developer.huawei.com/consumer/cn/download/

可以确定代码没问题的。真机运行是正常的。

cke_830.jpeg

Column() {
      List() {
        ListItem(){
          Text("         测试1")
            .width('100%')
            .height(50)
        }
        ListItem(){
          Text("          测试2")
            .width('100%')
            .height(50)
        }
        ListItem(){
          Text("          测试3")
            .width('100%')
            .height(50)
        }
      }
      .divider({
        color:Color.Red,
        strokeWidth: 1,
      })
      .width('100%')
      .layoutWeight(1)

      Button("退出登录")
        .width("80%")
        .height(40)
        .onClick(() => {
          // this.dialogController.open()
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor("#F5F5F5")
  }

List divider属性的strokeWidth值设置为低于1时,模拟器由于分辨率问题导致看不清晰,真机的渲染逻辑更贴近实际环境,优先使用真机进行调试。

解决方案如下:

可以将divider中的strokeWidth值修改为1。

推荐不使用divider属性,手动添加一个Divider组件作为分割线。

没在真机上试过, 但是strokeWidth确实是1. 目前解决方案就是手动给item最下边加Divider组件了,只不过最后一条会多条线,

这段代码存在几个关键问题,主要集中在HarmonyOS ArkUI的组件使用规范上。

  1. Repeat组件位置错误 Repeat组件必须直接作为滚动容器(List/Grid等)的子组件使用。当前代码将Repeat放在List的顶层,但内部用ListItem包裹,这违反了ArkUI V2规范。

  2. 重复包裹ListItem 在List容器中,每个子项必须直接使用ListItem。当前通过 Repeat.each 生成ListItem,又在内部用 ListItem{...} 二次包裹,导致层级冲突。

  3. divider()位置错误 divider() 修饰符应作用于ListItem而非List。当前代码将其附加到List末尾,会导致分隔线渲染异常。

  4. 边缘效果冲突 EdgeEffect.Spring效果与自定义下拉刷新逻辑冲突(如用户可能实现的下拉刷新)。当前代码在未处理触摸事件的情况下强制启用弹簧效果,可能导致手势识别异常。

修复后的代码

List() {
  // Repeat直接作为List的子组件,且内部不再包裹ListItem
  Repeat(this.setInfoItemlist)
    .each((reItem) => {
      // 关键修改:移除外层ListItem
      this.setItemInfo(reItem.item)
    })
}
.divider({  // 分隔线作用于ListItem
  color: Color.Red,
  strokeWidth: 1,
  startMargin: 10,
  endMargin: 10
})
// 谨慎启用边缘效果(需配合手势逻辑)
// .edgeEffect(EdgeEffect.Spring)
.width('100%')

大哥首先 Repeat使用没啥问题啊和官方的示例代码一样, 就算不用 Repeat, list子组件放几个ListItem也还是不好使,. 还有ListItem没有设置divider的方法啊 divider()就是list的方法. 目前我这边解决方案是手动加divider组件了, 感觉这个和安卓的listview一样,官方的divider方法都不太好用,

有什么异常,你说出来

在HarmonyOS Next中,List组件的divider显示异常通常与样式设置或API使用方式有关。请检查divider属性是否在List组件的属性中正确配置,并确认其样式定义是否符合当前版本规范。部分场景下,可能需要通过自定义组件或调整布局参数来解决。

根据你提供的代码和截图,问题在于 ListItem 的高度设置与 divider 的预期渲染位置发生了冲突。

在你的代码中,每个 ListItem 内部都明确设置了 .height(50)Listdivider 属性用于在列表项之间绘制分隔线,其渲染逻辑依赖于 ListItem 的布局边界。

核心原因分析: divider 默认会基于 ListItem 的完整高度区域进行计算和绘制。当你为 ListItem 内的子组件(如 Text)设置了固定高度(50vp),但 ListItem 容器本身可能仍会尝试填充或适应其内容,这可能导致 divider 的定位计算出现偏差,从而出现错位、重复绘制或显示在非预期的位置。

解决方案: 将高度约束直接应用到 ListItem 组件上,而不是其内部的子组件。这为 List 的布局系统提供了明确的每一项的尺寸边界,divider 便能在此清晰边界的基础上正确绘制。

修改后的代码片段如下:

List() {
  ListItem(){
    Text("测试1")
      .width('100%')
  }
  .height(50) // 将高度设置移至 ListItem

  ListItem(){
    Text("测试2")
      .width('100%')
  }
  .height(50) // 将高度设置移至 ListItem

  ListItem(){
    Text("测试3")
      .width('100%')
  }
  .height(50) // 将高度设置移至 ListItem
}
.divider({
  color: Color.Red,
  strokeWidth: 1,
})
.width('100%')

关键修改点: 移除 Text 组件上的 .height(50),并将 .height(50) 设置移至对应的 ListItem() 闭包后。这样确保了每个列表项容器具有明确定义的高度,divider 的绘制引擎便能基于这些容器的边界正确生成项间的分隔线。

回到顶部