列表 是最常用到的组件
一 ForEach
渲染控制语法————Foreach
Foreach的作用
- 遍历数组项,并创建相同的布局组件块
- 在组件加载时, 将数组内容数据全部创建对应的组件内容, 渲染到页面上
const swiperImage: Resource[] ={$r("app.media.ic_home"),$r("app.media.ic_coupons"),$r('app.media.ic_internal_price')
};
Swiper(){Foreach(swiperImage, (item: Resource) =>{Image(item).width("100%")...}, (item: Resource) => JSON.stringify(item))
}
二. LazyForEach
渲染控制语法 ————LazyForeach
- 使用 LazyForeach时,框架会根据滚动容器可视区域按需创建组件, 当组件滑出可视区域外时,框架会进行组件销毁回收以降低内存占用, 提高首次加载的速度
- 不可滚动容器使用LazyForeach, 其会退化为Foreach, 全部创建内容
- 使用的数据源需要继承 IDatasource 接口
WaterFlow(){LazyForEach(this.datasource, (item: ProductBean) =>{FlowItem(){FlowItemComponent({item: item})}}, (item: ProductBean) => JSON.stringify(item))
}
三 List列表
List 支持懒加载能力
List(){ForEach(mainViewModel.getSettingListData(),(item: ItemData) =>{ListItem(){this.settingCell(item)}},item => item.toString())
}.divider({...})
四 Grid网格布局
实现二维布局, 可以根据rowsTemplate, columnTemplate 设置行数和列数
Grid(){ForEach(mainViewModel.getFirstGridData(),(item: ItemData) =>{GridItem(){Column(){Image(item.img)Text(item.title)}}}, item => item.toString())
}.rowsTemplate("1fr 1fr")
.columnsTemplate("1fr 1fr 1fr 1fr")
.rowsGap(12)
.columnsGap(8)
网络显示如下图 方框所示
五 性能优化
在大数据量情况下, 例如超过10万
使用ForEach加载 List, 会出现白屏, 使用LazyForEach 不会白屏。
ForEach为什么会有性能问题, 假设有1万条数据, 手机的可视区域只能显示5条, 剩余9千多条也会全量加载,ForEach的加载原理就是这样。
LazyForEach实现了按需加载, 减少了页面首次启动时一次性加载数据的时长, 减少了内存峰值。
要对性能优化, 就需要引入指标来进行分析、比较
我们可以从4方面进行优化
- 优化1 懒加载
- 优化2 缓存列表项
- 优化3 组件复用
- 优化4 布局优化
注意: 通过设置cachedCount 来指定缓存数量。
不同cachedCount 对列表滑动帧率的影响
一般而言, 缓存的cachedCount= n/2(n为一屏显示的列表数) 的时候, 效果较好。
如果列表项中需要显示网络数据, 而网络数据加载较慢,为了提升列表信息的浏览效率和浏览体验, 我们可以适当的多设置一些缓存数量;
如果列表中需要加载一些大图或者视频等, 占用的内存较大,为了减少内存的占用, 我们需要适当地减少缓存数量的设置 (cachedCount < n/2).