获取当前List控件,第一个可见Item的位置 HarmonyOS 鸿蒙Next
获取当前List控件,第一个可见Item的位置 HarmonyOS 鸿蒙Next
现在有一个List组件
他滚动到了某个位置。我想知道目前第一个可见的Item,和最后一个可见的Item的位置。请问该如何获取?
Andorid系统上有该功能实现。
LinearLayoutManager.findFirstVisibleItemPosition();
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 })
}
}
}
更多关于获取当前List控件,第一个可见Item的位置 HarmonyOS 鸿蒙Next的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,获取List控件中第一个可见Item的位置可以通过ListController
的getFirstVisibleItemIndex
方法实现。ListController
是List控件的控制器,用于管理和操作List的视图和布局。getFirstVisibleItemIndex
方法返回当前可见区域内第一个Item的索引值。
示例代码如下:
let listController: ListController = ...; // 获取ListController实例
let firstVisibleIndex: number = listController.getFirstVisibleItemIndex();
console.log("第一个可见Item的索引:", firstVisibleIndex);
该方法直接返回当前List控件中第一个可见Item的索引,无需额外处理。适用于需要动态获取List控件可见区域内容的场景。