# ListItemReuse **Repository Path**: chinasoft6_ohos/listitemreuse ## Basic Information - **Project Name**: ListItemReuse - **Description**: list列表Item项复用 - **Primary Language**: Unknown - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-09-02 - **Last Updated**: 2021-09-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # HarmonyOS JS开发列表项Item的复用示例 #### 效果演示 ![效果演示](https://images.gitee.com/uploads/images/2021/0902/113925_0ad1afd9_8627638.gif "ListItemReuse.gif") #### 介绍       看了效果演示,大家一定很疑惑,不是有提供基础组件list、list-item,为什么有直接的不用?       因为之前碰到需要实现一个item项上下切换的效果,list-item设置“position: fixed”可以达到位置显示效果,但是设置“position: absolute”并没有什么用。由于使用列表时并不一定是在整个界面的起始位置,使用“position: fixed”需要计算它上面组件的高度之和,使用“position: absolute”相对父元素定位,相对实现起来简单很多。如果我们不使用list,我们就需要实现一个类似list的组件。由于js没有类似于java的scrollview组件,我们可以使用list、list-item(仅一个)来模拟类似于java-scrollview组件的效果。       实现列表,我们使用for循环创建了多个item。数据量特别大时,我们会实现分页,但是分页机制是把新页数据添加到原有数据而不是替换,就需要创建几千甚至上万的item。出于对手机性能的考虑,于是就想实现一个item项可复用的list组件。         这里不介绍item项的切换,仅介绍实现item复用的方法、思路,如关注item切换可关注后面的文章。 #### 利用list、list-item(一个)实现滚动效果       这里很简单,即将list、list-item当一个组件来使用,当里面内容高度超过list组件高度时,会有滚动条出现。代码如下: ```html
{{$idx}}:999999999999999--{{this.showlist[$idx].value}}
``` #### 向上滑动item复用机制       我们向上滑动时,上面的item项被滚动到不可见区域,我们可以将其挪到列表下方展示。需要实现item项的位置变化,可以使用position与top样式组合控制,当position设置为absolute相对于父元素进行定位,top可以控制item具体父元素上边框的距离。下面我们通过变动top,来实现上滑时item复用。具体hml代码如下: ```html
{{$idx}}:999999999999999--{{this.showlist[$idx].value}}
```       1) totalheight,页面可滚动高度,item的数量乘以item的高度。       2) showlist,页面展示的数据并非列表的数据,他跟加载item的个数相同,item的个数为页面可展示的个数加预加载item的个数(这个可以自己设置);showlist当中某项数据除了包括item的数据(value),还要包括item距离父元素顶部的距离(top)。       3) 父元素捕获scroll滚动事件,将顶部不可见元素加载新数据复用到列表下方,但是scroll的滚动参数并不能满足我们的需要,此时通过currentOffset方法捕获滑动偏移量来计算组件展示位置。 js代码: ```javascript //list组件当前滑动的偏移量 let xy = this.$element("mylist").currentOffset(); //判断当第一个item不可见时将其复用到列表的最下方 if(xy.y>this.lasty && this.lastlenghtthis.showlist.length && this.lastlenght > this.showlist.length + parseInt((xy.y-this.height)/this.height)){ //获取当前显示的最后一个item项,即界面for循环展示的div元素 let item = this.activelist.pop(); //将最后一个放到记录表的第一个 this.activelist.unshift(item); //新申明一个list变量装载界面循环展示的数据 var list = []; for (var index = 0; index < this.showlist.length; index++) { if(index == item){ //将当前item项放到列表第一个展示,利用top变量控制,数据展示其位置该展示的数据 list.push({ value:this.list[this.lastlenght-this.showlist.length-1], top:this.height*(this.lastlenght-this.showlist.length-1) }); }else{ //其他item项不变 list.push(this.showlist[index]) } } //将其赋值给界面展示的数据变量 this.showlist = list; //界面展示的item项-1 this.lastlenght -= 1; } //记录上一次的滚动位置 this.lasty = xy.y; ``` #### 总结       这里实现的是一个简单的item项复用效果及其思路,我们使用的时候需要考虑屏幕的展示的item数目、需要缓存提前展示的item数目、列表项的分页等等。另外我们需要注意,对象的根地址未变,其对象里面子项内容变化,页面并不会刷新,这个可以持续关注鸿蒙api,后期可能会有更新。说到这里,简单的item复用思路、方法已介绍完毕,希望能帮到大家,也欢迎大家指正其中的不足。 #### 代码参考 [https://gitee.com/chinasoft6_ohos/listitemreuse](https://gitee.com/chinasoft6_ohos/listitemreuse) 作者 :陈巧银 ## 更多原创内容请关注:[中软国际 HarmonyOS 技术学院](https://harmonyos.51cto.com/column/59) 入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,共建鸿蒙生态,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。