HarmonyOS 鸿蒙Next 使用LazyForEach做分页查询刷新列表后页面跳到第一条(看视频)如何解决

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 使用LazyForEach做分页查询刷新列表后页面跳到第一条(看视频)如何解决

关键代码如下

Refresh({refreshing: $$this.isRefreshing, builder: this.customRefreshComponent()}){
List(){
LazyForEach(this.orderListData,(item: ShopDeviceOrderListContent)=>{
OrderListItem({orderInfo: item, copy: (id: string)=> { this.onCopy(id) }})
.width(‘93%’).margin({top: 10}).borderRadius(16).shadow(ShadowStyle.OUTER_DEFAULT_SM)
}, (item: ShopDeviceOrderListContent) => item.id)

ListItem(){
Text(“没有更多数据”)
.fontSize(16)
.fontColor($r(‘app.color.colorText3’))
.width(‘100%’)
.height(40)
.textAlign(TextAlign.Center)
.visibility(this.noMoreShow && this.orderListData.totalCount() > 0 ? Visibility.Visible : Visibility.None)
}
}
.width(‘100%’)
.height(‘100%’)
.alignListItem(ListItemAlign.Center)
.onReachEnd(() =>{
if (!this.noMoreShow){
this.initData()
}
})
}
.onRefreshing(()=>{
this.query.page = 0
this.initData()
})

initData(){
if (this.loading){
return
}
this.loading = true
efRcpClientApi.get<ShopDeviceOrderListData>({
url: deviceOrder,
query: this.query,
isParams: true
}).then((data)=>{
if (this.query.page == 0){
this.orderListData = new MyOrderDataSource()
}
if (data.data?.content != undefined){
let list : ShopDeviceOrderListContent[] = data.data.content
for (let index = 0; index < list.length; index++) {
let data : ShopDeviceOrderListContent = list[index] as ShopDeviceOrderListContent
for(let dict of this.paymentMethodDictList){
if (data.payType == dict.value){
data.payMethodName = dict.label
}
}
this.orderListData.pushData(data)
}
if (list.length < this.query.size){
//没有更多数据
this.noMoreShow = true
} else {
this.query.nextPage()
}
} else {
let bean : ErrorBean = JSON.parse(JSON.stringify(data.data)) as ErrorBean
showToast(bean.message!)
}
this.loading = false
this.isRefreshing = false
})
}

export class MyOrderDataSource extends OrderBasicDataSource {

private dataArray: ShopDeviceOrderListContent[] = [];

public totalCount(): number {
return this.dataArray.length;
}

public getData(index: number): ShopDeviceOrderListContent {
return this.dataArray[index];
}

public addData(index: number, data: ShopDeviceOrderListContent): void {
this.dataArray.splice(index, 0, data);
this.notifyDataAdd(index);
}

public pushData(data: ShopDeviceOrderListContent): void {
this.dataArray.push(data);
this.notifyDataAdd(this.dataArray.length - 1);
}

public deleteData(index: number): void {
this.dataArray.splice(index, 1);
this.notifyDataDelete(index);
}

public changeData(index: number): void {
this.notifyDataChange(index);
}
}

export class OrderBasicDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private originDataArray: ShopDeviceOrderListContent[] = [];

/constructor(list: CustomBeanType[]) {
this.originDataArray = list
}
/

public totalCount(): number {
return 0;
}

public getData(index: number): ShopDeviceOrderListContent {
return this.originDataArray[index];
}

registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
//console.info(‘add listener’);
this.listeners.push(listener);
}
}

unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
//console.info(‘remove listener’);
this.listeners.splice(pos, 1);
}
}

notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}

notifyDataAdd(index: number): void {
this.listeners.forEach(listener => {
listener.onDataAdd(index);
})
}

notifyDataChange(index: number): void {
this.listeners.forEach(listener => {
listener.onDataChange(index);
})
}

notifyDataDelete(index: number): void {
this.listeners.forEach(listener => {
listener.onDataDelete(index);
})
}

notifyDataMove(from: number, to: number): void {
this.listeners.forEach(listener => {
listener.onDataMove(from, to);
})
}

notifyDatasetChange(operations: DataOperation[]): void {
this.listeners.forEach(listener => {
listener.onDatasetChange(operations);
})
}
}

3 回复

页面跳到第一条是个bug,我是想要解决这个bug。视频上传不了,我做了个动图

我自己另外写的demo运行没问题,代码大部分跟我这个功能的代码一样,但是不知道为啥每次分页请求回来,数据是增加的,但是列表的位置跳到第一条

如果你是想要在到onReachEnd的时候就跳回到第一条listitem的话,使用scrollEdge就能做到,使用下面的方法:

private scroller: ListScroller = new ListScroller()
.onReachEnd(() =>{
    if (!this.noMoreShow){
        this.initData()
        this.scroller.scrollEdge(Edge.Top)
    }
})<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

如果理解的意思有偏差,麻烦提供下ShopDeviceOrderListContent、efRcpClientApi、OrderListItem自定义组件、this.query的定义也要麻烦发下,还有视频现象是不是忘记了上传。

或者提供个更加简单的场景复现demo一起看下呢

在HarmonyOS鸿蒙Next系统中,使用LazyForEach进行分页查询时,如果刷新列表后页面跳回到第一条,这通常是由于数据刷新逻辑或UI更新机制导致的。以下是一些可能的原因及检查点,帮助你定位并解决问题:

  1. 数据刷新逻辑:检查数据刷新时是否重置了滚动位置。如果分页数据更新后重新设置了列表的源数据,确保不改变当前的滚动状态或手动恢复滚动位置。

  2. UI更新机制:LazyForEach在数据变化时可能会重新构建UI,导致滚动状态丢失。尝试在数据更新后,通过状态管理恢复滚动位置,例如使用ScrollView的scrollTo方法。

  3. 视频播放影响:如果页面中包含视频播放,视频播放状态或页面生命周期变化可能影响列表的滚动状态。确保视频播放逻辑与列表滚动逻辑相互独立。

  4. 调试与日志:增加日志输出,跟踪数据刷新和UI更新的时机,以及滚动位置的变化,有助于定位问题。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。希望这些信息能帮助你解决问题。

回到顶部