ListItem 组件渲染错误空白内容
使用 ListItem + Stack 组件开发,ListItem 向下滑动时,出现白屏
使用 ArkUI Inspector 分析,空白内容显示 contens is not on device screen
使用工具
DevEco Studio NEXT Developer Preview2
定位过程
1,确定布局
根据组件树结构确定出现问题的页面总体布局为List+List(ListItem(Stack))嵌套,出现空白渲染的组件是子List。
2,异常排查
2.1,从组件树ListItem起始位置向下排查:
从LazyForEach可以看出,List总共渲染8个ListItem,需要从这8个ListItem中找出有异常的ListItem。
组件树提供了组件的大小和位置信息,从上图能看出ListItem组件的位置信息:
发现异常,ListItem的宽度为0,表现为空白
2.2,找出正常显示ListItem:
继续向下寻找ListItem,发现显示正常的信息为:
2.3,对比异常:
经过对比发现,异常显示空白的ListItem组件树信息看,高度为332占用了List的高度,但是宽度为0,表现为空白占用了List列表,但未显示任何信息
3,分析代码
3.1,ListItem:
异常情况下ListItem宽度为0,高度正常,异常场景是编辑状态修改,导致ListItem重新布局,宽度异常,则定位先将ListItem宽度设置为固定值,并且将ListItem背景颜色设置为红色,运行发现
ListItem显示正常,但Stack内容丢失
3.2,ListItem->Stack:
结合组件树Stack自定义的容器组件
结构为
Row + Row
{x:-42} + {x: 0}
经过animateTo动画操作左侧Row 和 右侧Row进行平移。
效果类似下图:
3.3,ListItem->Stack->animateTo:
根据下拉刷新后,列表恢复显示,与开始编辑场景区别在于有无动画,动画修改偏移量(状态变量)来改变toggle和stack位置信息,ListItem内部布局会修改,先将动画关掉查看效果。
关掉动画后,ListItem显示正常(背景色红色,Stack内容显示正常),继续分析源码
3.4,ListItem->Stack->animateTo->aboutToAppear:
分析代码,animateTo在aboutToAppear中,并且通过对象保存动画状态isAnimating,由于其他原因开发者在LazyForEach中重复创建ListItem,通过数组中对象保存状态导致滑动过程中重复调用aboutToAppear,此时自定义组件还未执行build,组件并未生成,重复调用动画并且在build之前导致渲染异常。
根因总结
根据排查,发现ListItem中的自定义组件在aboutToAppear中重复调用显式动画animateTo导致渲染异常。
将显式动画修改成属性动画.animation(),并且在参数onFinish中设置对象isAnimating为false,防止重复动画。