HarmonyOS 列表List相关问题

list中存在多个item,由于宽度不同导致部分item不完全可见,想知道完全可见这部分demo的下标。

1、怎么获取List中第一个完全可见的item下标。

2、怎么获取List中最后一个完全可见的item下标。

3、怎么判断List中某个item是否完全可见。

HarmonyOS
2024-09-24 10:35:40
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
superinsect

HarmonyOS没有可以直接获取第一个和最后一个完全可见元素的接口,需要使用onScrollIndex和OnScroll回调配合实现。onScrollIndex能获取当前窗口内所有可见的item,在onscrollstop中,通过获取可见item的坐标和父容器坐标的比较得到完全可见的item的index。

具体DEMO如下,以list中text左对齐为例:

@Entry  
@Component  
struct ListExample {  
  private arr: number[] = []  
  private scrollerForList: Scroller = new Scroller()  
  @State startStr: string = ''  
  
  startIndex = 0  
  endIndex = 0  
  initState = true  
  rowWidth = 400  
  private judgeVisible() {  
    this.startStr = ""  
    // 判断start是否遮挡  
    let rect = this.scrollerForList.getItemRect(this.startIndex)  
    // 左对齐的场景下,如果左边第一个元素完全可见,那么元素x坐标(相对row的坐标)误差在1以内  
    if (!((-1 < rect.x) && (rect.x < 1)))  
    {  
      this.startIndex = this.startIndex + 1  
    }  
    rect = this.scrollerForList.getItemRect(this.endIndex)  
    // 左对齐的场景下,如果右边第一个元素完全可见,那么元素x坐标加上元素宽度 应该在row的宽度范围之内(还需要考虑1px的误差)  
    if (!((rect.x + rect.width) > this.rowWidth - 1 && (rect.x + rect.width) < this.rowWidth + 1))  
    {  
      this.endIndex = this.endIndex - 1  
    }  
    if (this.startIndex <= this.endIndex) {  
      this.startStr = String(this.startIndex) + "," + String(this.endIndex)  
    }else {  
      this.startStr = "没有能全部显示的控件"  
    }  
  }  
  
  aboutToAppear() {  
    for (let i = 0; i < 20; i++) {  
      this.arr.push(i)  
    }  
  }  
  build() {  
    Column() {  
      Row() {  
        Text(this.startStr)  
          .fontSize(10)  
          .textAlign(TextAlign.Start)  
          .fontColor(Color.Red)  
      }  
      .height(100)  
      .backgroundColor(Color.Gray)  
      .opacity(0.3)  
      .width("100%")  
  
      Row() {  
        List({ space: 20, initialIndex: 0, scroller: this.scrollerForList }) {  
          ForEach(this.arr, (item: number) => {  
            ListItem() {  
              Text('' + item)  
                .width('100%').height(100).fontSize(16)  
                .textAlign(TextAlign.Center)  
            }  
            .borderRadius(10).backgroundColor(0xFFFFFF)  
            .width(item%4==0 ? 500 : 50)  
            .height(200)  
          }, (item: number) => JSON.stringify(item))  
        }  
        .chainAnimation(true)  
        .edgeEffect(EdgeEffect.Spring)  
        .listDirection(Axis.Horizontal)  
        .height('100%')  
        .width(this.rowWidth)  
        .scrollSnapAlign(ScrollSnapAlign.START)  
        .borderRadius(10)  
        .backgroundColor(0xDCDCDC)  
        .divider({ strokeWidth: 2, color: 0xFF00000, startMargin: 10, endMargin: 40 })  
        .onScrollIndex((start, end)=>{  
          this.startIndex = start  
          this.endIndex = end  
          // 界面初始显示的时候,不会触发onScrollStop事件,在这里判断可见性  
          if (this.initState == true) {  
            this.judgeVisible()  
            this.initState = false  
          }  
        })  
        .onScrollStop(()=>{  
          // 缓存开始结束索引: 在最后一页多次右滑时候,不会触发onScrollIndex  
          let tmpStart = this.startIndex  
          let tmpEnd = this.endIndex  
          this.judgeVisible()  
          this.startIndex = tmpStart  
          this.endIndex =tmpEnd  
        })  
      }  
      .width('100%')  
      .height('100%')  
      .backgroundColor(0xDCDCDC)  
      .padding({ top: 10 })  
    }  
  }  
}
分享
微博
QQ
微信
回复
2024-09-24 15:48:17
提问
该提问已有0人参与 ,帮助了0人