HarmonyOS 鸿蒙Next 如何获取Grid组件中 Item距离顶部的偏移量
HarmonyOS 鸿蒙Next 如何获取Grid组件中 Item距离顶部的偏移量
Grid的一些使用场景,如附近中红色区域是一个Grid组件
1、如何让Grid自动滚动到顶部?比如说在全部这个Tab中滑动到中间的位置,切换到背包后再又切换到全部Tab,期待Grid是滑动到顶部的。
2、如何获取Grid滑动后监听到可见的第一个Item距离Grid的偏移量?比如我在全部这个Tab中滑动到了中间位置,关闭了面板后,下载打开面板期待全部这个分类下滑动到关闭的位置?
更多关于HarmonyOS 鸿蒙Next 如何获取Grid组件中 Item距离顶部的偏移量的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
可以参考如下demo: // xxx.ets
@Entry
@Component
struct TabsExample {
@State fontColor: string = '#182431'
@State selectedFontColor: string = '#007DFF'
@State currentIndex: number = 0
private controller: TabsController = new TabsController()
private scroller: Scroller = new Scroller()
private scroller1: Scroller = new Scroller()
@State numbers1: String[] = ['0', '1', '2', '3', '4']
@State numbers2: String[] = ['0', '1', '2', '3', '4', '5']
curScrollOffset1: number = 0
@State clickedContent: string = ""
layoutOptions3: GridLayoutOptions = {
regularSize: [1, 1],
onGetRectByIndex: (index: number) => {
if (index == 0) {
return [0, 0, 1, 1]
} else if (index == 1) {
return [0, 1, 2, 2]
} else if (index == 2) {
return [0, 3, 3, 3]
} else if (index == 3) {
return [3, 0, 3, 3]
} else if (index == 4) {
return [4, 3, 2, 2]
} else {
return [5, 5, 1, 1]
}
}
}
@Builder
tabBuilder(index: number, name: string) {
Column() {
Text(name)
.fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor)
.fontSize(16)
.fontWeight(this.currentIndex === index ? 500 : 400)
.lineHeight(22)
.margin({ top: 17, bottom: 7 })
Divider()
.strokeWidth(2)
.color('#007DFF')
.opacity(this.currentIndex === index ? 1 : 0)
}.width('100%')
}
build() {
Column() {
Button('tabs停止滚动并存储位置')
.width(100).height(100)
.onClick(()=>{
AppStorage.setOrCreate('this.currentIndex', this.currentIndex); //记录切换的tabs中的index, 因为这里index === 1为例 记录滚动偏移量,可以this.currentIndex设置为1
AppStorage.setOrCreate('this.curScrollOffset1', this.curScrollOffset1); // 以index === 1为例 记录滚动偏移量
})
Button('点击滚动到之前的位置')
.width(100).height(100)
.onClick(()=>{
this.currentIndex = Number(AppStorage.get('this.currentIndex')) // 获取记录切换的tabs中的index
this.curScrollOffset1 = Number(AppStorage.get('this.curScrollOffset1')) //获取 以index === 1为例 记录滚动偏移量
this.scroller.scrollTo({ xOffset: 0, yOffset: this.curScrollOffset1, animation: { duration: 100, curve: Curve.Ease } }) //由于只能上下移动,所以改变yOffset即可
})
Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
TabContent() {
Scroll(this.scroller) {
Grid() {
ForEach(this.numbers1, (day: string) => {
ForEach(this.numbers2, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('100%')
.height('150%')
}.backgroundColor('#ffffed00')
}
.tabBar(this.tabBuilder(0, 'green'))
TabContent() {
Scroll(this.scroller1) {
Grid() {
ForEach(this.numbers1, (day: string) => {
ForEach(this.numbers2, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.rowsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('100%')
.height('150%')
}
.backgroundColor('#00ef2323')
.onWillScroll((xOffset: number, yOffset: number, scrollState: ScrollState) => {
this.curScrollOffset1 += yOffset //上下滑动,只记录yOffset即可
console.info('this.curScrollOffset1' + ' ' + this.curScrollOffset1)
})
}
.tabBar(this.tabBuilder(1, 'blue'))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
if(index === 0){
this.scroller.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 100, curve: Curve.Ease } }) // index切换时,数据滚动到顶部
}else{
this.scroller1.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 100, curve: Curve.Ease } }) // 如果想验证index === 2的偏移量是否正确,可以去掉此段代码,记录偏移量
}
this.currentIndex = index
console.log("this.currentIndex"+ this.currentIndex)
})
.width(360)
.height('100%')
.margin({ top: 52 })
.backgroundColor('#F1F3F5')
}
.width('100%').height('100%')
}
}
scrollTo: 滑动到指定位置。
参考demo: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-container-scroll-V5#scrollto
onWillScroll: 回调当前帧将要滚动的偏移量和当前滚动状态和滚动操作来源,其中回调的偏移量为计算得到的将要滚动的偏移量值,并非最终实际滚动偏移。可以通过该回调返回值指定Scroll将要滚动的偏移。
如果Grid外层不想嵌套Scroll,
可以参考如下demo:
@Entry
@Component
struct TabsExample {
@State fontColor: string = '#182431'
@State selectedFontColor: string = '#007DFF'
@State currentIndex: number = 0
private controller: TabsController = new TabsController()
private scroller: Scroller = new Scroller()
private scroller1: Scroller = new Scroller()
@State numbers1: String[] = ['0', '1', '2', '3', '4']
@State numbers2: String[] = ['0', '1', '2', '3', '4', '5']
curScrollOffset1: number = 0
@State clickedContent: string = ""
layoutOptions3: GridLayoutOptions = {
regularSize: [1, 1],
onGetRectByIndex: (index: number) => {
if (index == 0) {
return [0, 0, 1, 1]
} else if (index == 1) {
return [0, 1, 2, 2]
} else if (index == 2) {
return [0, 3, 3, 3]
} else if (index == 3) {
return [3, 0, 3, 3]
} else if (index == 4) {
return [4, 3, 2, 2]
} else {
return [5, 5, 1, 1]
}
}
}
@Builder
tabBuilder(index: number, name: string) {
Column() {
Text(name)
.fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor)
.fontSize(16)
.fontWeight(this.currentIndex === index ? 500 : 400)
.lineHeight(22)
.margin({ top: 17, bottom: 7 })
Divider()
.strokeWidth(2)
.color('#007DFF')
.opacity(this.currentIndex === index ? 1 : 0)
}.width('100%')
}
build() {
Column() {
Button('tabs停止滚动并存储位置')
.width(100).height(100)
.onClick(()=>{
AppStorage.setOrCreate('this.currentIndex', this.currentIndex); //记录切换的tabs中的index, 因为这里index === 1为例 记录滚动偏移量,可以this.currentIndex设置为1
AppStorage.setOrCreate('this.curScrollOffset1', this.scroller1.currentOffset().yOffset); // 以index === 1为例 记录滚动偏移量
})
Button('点击滚动到之前的位置')
.width(100).height(100)
.onClick(()=>{
this.currentIndex = Number(AppStorage.get('this.currentIndex')) // 获取记录切换的tabs中的index
this.curScrollOffset1 = Number(AppStorage.get('this.curScrollOffset1')) //获取 以index === 1为例 记录滚动偏移量
this.scroller.scrollTo({ xOffset: 0, yOffset: this.curScrollOffset1, animation: { duration: 100, curve: Curve.Ease } }) //由于只能上下移动,所以改变yOffset即可
})
Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
TabContent() {
Grid(this.scroller) {
ForEach(this.numbers1, (day: string) => {
ForEach(this.numbers2, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('100%')
.height('100%')
.backgroundColor('#ffffed00')
}
.tabBar(this.tabBuilder(0, 'green'))
TabContent() {
Grid(this.scroller1) {
ForEach(this.numbers1, (day: string) => {
ForEach(this.numbers2, (day: string) => {
GridItem() {
Text(day)
.fontSize(16)
.backgroundColor(0xF9CF93)
.width('100%')
.height('100%')
.textAlign(TextAlign.Center)
}
}, (day: string) => day)
}, (day: string) => day)
}
.columnsTemplate('1fr 1fr 1fr 1fr 1fr')
.columnsGap(10)
.rowsGap(10)
.width('100%')
.height('100%')
.backgroundColor('#00ef2323')
}
.tabBar(this.tabBuilder(1, 'blue'))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
if(index === 0){
this.scroller.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 100, curve: Curve.Ease } }) // index切换时,数据滚动到顶部
}else{
this.scroller1.scrollTo({ xOffset: 0, yOffset: 0, animation: { duration: 100, curve: Curve.Ease } }) // 如果想验证index === 2的偏移量是否正确,可以去掉此段代码,记录偏移量
}
this.currentIndex = index
console.log("this.currentIndex"+ this.currentIndex)
})
.width(360)
.height('100%')
.margin({ top: 52 })
.backgroundColor('#F1F3F5')
}
.width('100%').height('100%')
}
}
更多关于HarmonyOS 鸿蒙Next 如何获取Grid组件中 Item距离顶部的偏移量的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next系统中,获取Grid组件中Item距离顶部的偏移量可以通过访问Grid组件的布局信息和Item的位置信息来实现。具体操作步骤如下:
-
获取Grid组件的Layout信息: 使用
Component.getLayoutParams()
方法获取Grid组件的布局参数,该参数包含组件的尺寸和位置信息。 -
遍历Grid中的Item: 使用Grid组件的
getChildCount()
和getChildAt(index)
方法遍历所有Item。 -
获取Item的顶部偏移量: 对于每个Item,使用
Component.getTop()
方法获取其相对于父组件(即Grid)顶部的偏移量。 -
累加父组件的偏移量: 如果Grid组件本身有相对于其父组件的偏移,需要累加这些偏移量以获得Item相对于整个布局顶部的最终偏移量。
示例代码(伪代码):
Grid grid = findComponentById(resourceId);
int gridTop = grid.getTop(); // Grid本身的顶部偏移量
for (int i = 0; i < grid.getChildCount(); i++) {
Component item = grid.getChildAt(i);
int itemTop = item.getTop(); // Item相对于Grid的顶部偏移量
int totalTop = gridTop + itemTop; // Item相对于整个布局的顶部偏移量
// 处理totalTop,例如存储或输出
}
注意:上述示例中的方法调用是基于组件的通用API,并非特定于鸿蒙系统的API,但原理相同。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html