怎么做商业网站模板,美工培训费用,鞍山网民,南京网站搭建介绍
本示例主要介绍了List组件实现二级联动#xff08;Cascading List#xff09;的场景。 该场景多用于商品种类的选择、照片不同类型选择等场景。
效果图 使用说明#xff1a;
滑动二级列表侧控件#xff08;点击没用#xff09;#xff0c;一级列表随之滚动。Cascading List的场景。 该场景多用于商品种类的选择、照片不同类型选择等场景。
效果图 使用说明
滑动二级列表侧控件点击没用一级列表随之滚动。当最后一次触屏在一级列表则滑动二级列表一级列表固定不动点击一级列表滑动没用二级列表随之滚动。点击一级列表可视区域边界时选中类别向中间移动
实现思路
使用两个List。一二级列表分别绑定不同的Scroller对象一级列表(tagLists)绑定classifyScroller对象二级列表绑定scroller对象。维护records数组一个item数量的前缀和records[i]表示第i1种类别的第一个item之前有多少个item这个数值等于records[i]表示第i1种类别的第一个item在itemList的下标使用List的onTouch.onScrollIndex组件方法,判断最后一次触屏是否在一级列表和一级列表的可视区域实现itemFindClassIndex(itemIndex:number)itemFindClassIndex(itemIndex:number)点击一级列表后通过一级列表的索引获取二级列表的索引调用scrollToIndex方法将一二级列表滚动到指定索引值滑动二级列表触发组件滚动事件后获取到列表可视区域第一个item对应的索引值通过二级列表索引获取一级列表索引调用scrollToIndex方法将一级列表滚动到指定索引值监听curClass变量onClassChange点击一级列表可视区域边界时一级列表将选中类别向中间移动
样例代码
interface IRange {start: number;end: number;
}//可视区间的开始和结尾
Entry
Component
struct Index {State itemList:string[][]; // 二级列表数据State classList:string[][]; // 一级列表数据State Watch(onClassChange) curClass:number-1//当前类别下标readonly eachClassCount:number[][6,4,4,6,5,6,4,4,6,5];//每一个类别item的数量private classScroller:Scrollernew Scroller();private itemScroller:Scrollernew Scroller();private records:number[][]; //一个前缀和 二级列表分组count数量private classVisualRange:IRange{start:0,end:0};private isClickClassList:booleanfalse; //上一次点击是否点击的是类别 true:滑动二级列表一级列表不跟着一起变化 flase滑动二级列表一级列表跟着一起变化aboutToAppear(): void {/*造数据*/for(let i0;i10;i){this.classList[this.classList.length]第${i1}类for(let j0;jthis.eachClassCount[i];j){this.itemList[this.itemList.length]第${i1}类 第${j1}个}}this.records[0]0;for(let i1;i10;i){//最后多一个方便二级item寻找一级classthis.records[i]this.records[i-1]this.eachClassCount[i-1];}}itemFindClassIndex(itemIndex:number):number{let classIndex:number0;for(let i0;i10;i){if(this.records[i]itemIndexitemIndexthis.records[i1]){classIndexi;break;}}return classIndex;}classFindItemIndex(classIndex:number):number{return this.records[classIndex];}onClassChange(){const startthis.classVisualRange.start,endthis.classVisualRange.end;if(this.curClassstart||this.curClassstart1){this.classScroller.scrollToIndex(Math.max(0,this.curClass-1),true)//向上一格作为可视区域第一个}else if(this.curClassend||this.curClassend-1){this.classScroller.scrollToIndex(Math.min(10,this.curClass1),true)//向下一格作为可视区域第一个}}build() {Row() {/*** 一级列表*/List({scroller:this.classScroller,space:10, initialIndex: 0}){ForEach(this.classList,(classItem:string,index:number){ListItem(){Text(classItem).width(100%).height(15%).backgroundColor(this.curClassindex?Color.Green:Color.Pink).onClick((){let itemIndexthis.classFindItemIndex(index);this.curClassindex;this.itemScroller.scrollToIndex(itemIndex,true)})}})}.width(30%).height(100%).margin({left:20,right:20}).scrollBar(BarState.Off).onTouch((){this.isClickClassListtrue;}).onScrollIndex((start,end){this.classVisualRange.startstart;this.classVisualRange.endend;})/*** 二级列表*/List({scroller:this.itemScroller,space:10}){ForEach(this.itemList,(item:string,index:number){ListItem(){Text(item).width(100%).height(17%).backgroundColor(#999999).onClick((){let classIndexthis.itemFindClassIndex(index);this.curClassclassIndex;this.classScroller.scrollToIndex(classIndex,true)})}})}.width(70%).height(100%).margin({left:20,right:20}).scrollBar(BarState.Off).onTouch((){this.isClickClassListfalse;})// 性能知识点:onScrollIndex事件在列表滚动时频繁执行在回调中需要尽量减少耗时和冗余操作例如减少不必要的日志打印.onScrollIndex((start,end){//二级列表滑动判断一级列表是否一起滑动if(!this.isClickClassList){let classIndexthis.itemFindClassIndex(start);this.curClassclassIndex;this.classScroller.scrollToIndex(classIndex,true)/*** scrollToIndex(value: number, smooth?: boolean, align?: ScrollAlign)* 性能知识点开启smooth动效时会对经过的所有item进行加载和布局计算当大量加载item时会导致性能问题。*/}})}.height(100%).width(100%)}
}扩展
把ForEach换成LazyEach懒加载当种类较多时要实现“点击一级列表可视区域边界时选中类别向中间移动”改进本案例会出现的问题