HarmonyOS鸿蒙Next中ListItem底部触底加载LoadingProgress()动画失效
HarmonyOS鸿蒙Next中ListItem底部触底加载LoadingProgress()动画失效 封装了一个loading的加载效果再拿到ListItem中使用的时候发现动画效果失效了

更多关于HarmonyOS鸿蒙Next中ListItem底部触底加载LoadingProgress()动画失效的实战教程也可以访问 https://www.itying.com/category-93-b0.html
背景知识:
楼主在使用list+listIltem时,要注意一下边距问题。从上述你得代码调试过程中可以知道,Loading中添加了.margin({right:’-100%”])出现的问题,只要在源码基础上注释掉这个就可以了,但是注释掉后又会出现 Loading布局居左问题。建议楼主使用grid布局来进行网络布局。
问题解决:
代码实例:
interface ItemType {
name: string
age: number
}
@Component
export struct Loading {
@Prop isAllShow: boolean
build() {
if (this.isAllShow) {
Row() {
Text(`没有更多啦`)
.fontSize(14)
.fontColor('#BD4B1F')
}
.width('100%')
.height(30)
.justifyContent(FlexAlign.Center)
.margin({ top: 2 })
} else {
Row({ space: 5 }) {
Text('加载中')
.fontSize(9)
.fontColor('#BD4B1F')
LoadingProgress()
.width("30")
.height("30")
.color("#BD4B1F")
}
.height(30)
.width('100%')
.height("50")
.margin({ top: 5 })
.justifyContent(FlexAlign.Center)
}
}
}
@Entry
@Component
struct LoadingPage {
@State message: string = 'Hello World';
@State person: ItemType[] = [
{ name: "张三", age: 20 },
{ name: "李四", age: 22 },
{ name: "王五", age: 19 },
{ name: "赵六", age: 21 },
{ name: "钱七", age: 23 },
{ name: "孙八", age: 20 },
{ name: "周九", age: 24 },
{ name: "吴十", age: 18 },
{ name: "郑十一", age: 22 },
{ name: "王十二", age: 21 },
{ name: "刘十三", age: 19 },
{ name: "陈十四", age: 20 },
{ name: "杨十五", age: 25 },
{ name: "黄十六", age: 22 },
{ name: "赵十七", age: 18 },
{ name: "林十八", age: 21 },
{ name: "张十九", age: 23 },
{ name: "李二十", age: 20 },
{ name: "王二一", age: 19 },
{ name: "刘二二", age: 22 }
]
pushList() {
setTimeout(() => {
for (let i = 0; i < 20; i++) {
this.person.push({ name: `张三${i}`, age: i })
}
}, 2000)
}
build() {
Column() {
List() {
ForEach(this.person, (item: ItemType, index) => {
ListItem() {
Column() {
Row() {
Text('姓名:')
Text(item.name)
Text((index + 1).toString())
.margin({ left: 20 })
}
Row() {
Text('年龄:')
Text(item.age.toString())
}
}
.margin({ bottom: 20 })
.backgroundColor('#BD4B1F')
}
})
ListItem() {
Loading({ isAllShow: false })
}
.height(50)
}
.lanes(2)
.onReachEnd(() => {
this.pushList()
})
}
}
}
真机演示:

更多关于HarmonyOS鸿蒙Next中ListItem底部触底加载LoadingProgress()动画失效的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
感谢兄弟给的提示,解决办法已经找到了,采用ListItemGroup解决了,

问题已解决,将ListItem替换为ListItemGroup
这里的.margin({right: ‘-100%’})不删除是因为需要保持其“加载中”处于页面中间
ListItemGroup(){
Loading({isAllShow: false})
.margin({right: '-100%'})
}
.height(50)
/*ListItem(){
Loading({isAllShow: false})
.margin({right: '-100%'})
}
.height(50)*/

这是你提供的代码运行结果截图,未发现你所说的未见loading
按照下面改一下代码
1/ 删除异常边距
ListItem(){
Loading({isAllShow: false})
// 这个边距删除
}
.height(50)
2/ 在封装组件中添加尺寸
LoadingProgress()
.color("#BD4B1F")
.width(30) // 增加尺寸
.height(30)
3/ 使用标准列表布局并开启滚动事件
List()
.width('100%')
.height('100%')
.onScrollIndex((start: number, end: number) => {
if (end >= this.person.length - 1) {
this.pushList()
}
})
4/ 添加加载状态控制
@State isLoadMore: boolean = false
pushList() {
if (this.isLoadMore) return
this.isLoadMore = true
setTimeout(() => {
// 加载数据
this.isLoadMore = false
}, 2000)
}
感谢您的提问,为了更快解决您的问题,麻烦请补充以下信息:
完整的复现demo(通过描述中提供的代码未复现问题,加载动画正常)。
@Component
export struct Loading {
@Prop isAllShow: boolean
build() {
if (this.isAllShow) {
Row() {
Text(`没有更多啦`)
.fontSize(14)
.fontColor('#BD4B1F')
}
.width('100%')
.height(30)
.justifyContent(FlexAlign.Center)
.margin({ top: 2 })
} else {
Row({ space: 5 }) {
Text('加载中')
.fontSize(9)
.fontColor('#BD4B1F')
LoadingProgress()
.color("#BD4B1F")
}
.height(30)
.width('100%')
.margin({ top: 5 })
.justifyContent(FlexAlign.Center)
}
}
}
import { Loading } from "./Loading"
interface ItemType {
name: string
age: number
}
@Entry
@Component
struct Index {
@State person: ItemType[] = [
{ name: "张三", age: 20 },
{ name: "李四", age: 22 },
{ name: "王五", age: 19 },
{ name: "赵六", age: 21 },
{ name: "钱七", age: 23 },
{ name: "孙八", age: 20 },
{ name: "周九", age: 24 },
{ name: "吴十", age: 18 },
{ name: "郑十一", age: 22 },
{ name: "王十二", age: 21 },
{ name: "刘十三", age: 19 },
{ name: "陈十四", age: 20 },
{ name: "杨十五", age: 25 },
{ name: "黄十六", age: 22 },
{ name: "赵十七", age: 18 },
{ name: "林十八", age: 21 },
{ name: "张十九", age: 23 },
{ name: "李二十", age: 20 },
{ name: "王二一", age: 19 },
{ name: "刘二二", age: 22 }
]
pushList() {
setTimeout(() => {
for (let i = 0; i < 20; i++) {
this.person.push({name: `张三${i}`, age: i})
}
}, 2000)
}
build() {
Column() {
List() {
ForEach(this.person, (item: ItemType, index) => {
ListItem() {
Column() {
Row() {
Text('姓名:')
Text(item.name)
Text((index + 1).toString())
.margin({ left: 20 })
}
Row() {
Text('年龄:')
Text(item.age.toString())
}
}
.margin({ bottom: 20 })
.backgroundColor('#BD4B1F')
}
})
ListItem(){
Loading({isAllShow: false})
.margin({right: '-100%'})
}
.height(50)
}
.lanes(2)
.onReachEnd(() => {
this.pushList()
})
}
}
}
未复现问题,使用以上demo加载动效正常。建议将IDE升级到最新版本进行测试。
demo给全了没
.lanes(2, 10)
.margin({ top: 20, bottom: 135 })
.onReachEnd(() => {
})
在HarmonyOS Next中,LoadingProgress()动画在ListItem底部失效,通常是由于ListItem的复用机制和渲染优化导致的。List组件默认会回收屏幕外的ListItem以提升性能,这可能中断或重置正在进行的动画。
核心解决方案是确保动画组件在ListItem中具有稳定的状态管理。 以下是最直接有效的修复方法:
-
使用
if条件控制加载组件的渲染:将LoadingProgress包裹在条件渲染逻辑中,确保仅在加载状态激活时创建动画实例,避免复用导致的动画重置。List() { ForEach(this.data, (item: DataType) => { ListItem() { // 正常列表项内容 } }) // 底部加载组件 if (this.isLoading) { // 使用状态变量控制 ListItem() { LoadingProgress() .width(50) .height(50) } } }当
isLoading状态变为true时,ListItem会创建并开始动画;变为false时,组件销毁。这能确保动画每次都能正确初始化并播放。 -
为加载项设置明确的
key:如果加载组件是独立的ListItem,为其分配一个固定且唯一的key,防止列表在更新时错误复用该项。if (this.isLoading) { ListItem() { LoadingProgress() } .key('loading_indicator') // 设置固定key } -
检查状态更新与
List的交互:确保触发加载的isLoading状态变更是在主线程同步更新的,并且List的数据源(this.data)没有在加载过程中发生非预期的清空或重置,这可能导致整个列表重绘并打断动画。
根本原因:直接放置在ListItem中的LoadingProgress,在列表滚动或数据更新时,可能因为ListItem的实例被回收并用于渲染其他数据项,导致其内部动画状态被销毁。使用条件渲染是标准做法,它明确了该组件的生命周期与加载状态的绑定关系。
请优先采用第一种方案,它能最稳定地解决此问题。


