笔记九 :EgretH5通用MVC框架的操作:制作折叠菜单FoldList(UI部分)

前言:由于时间比较紧,这次的博客更偏向笔记性质,而不是教程性质,必须打开源代码,接着再一步一步参考以下的笔记,不然很多细节上的东西漏掉了会出现大量错误。

源代码见我的资源:笔记九Egret-折叠List源代码.zip

演示:

笔记九 :EgretH5通用MVC框架的操作:制作折叠菜单FoldList(UI部分)

第一步:按照MVC框架搭建规则搭建好基础界面(参考源代码src/example/module/demo/list的做法,以及下面的步骤)

  1. FoldListDemoController
  2. FoldListDemoView
  3. ViewConst
  4. DemoTest.ts (按钮监听)
  5. ControllerConst

 

第二步:建立好必须素材,包括两个item的皮肤以及view

  1. FoldItemSkin.exml
  2. ItemDemoSkin.exml
  3. FoldListSmallItemView.ts
  4. FoldListBigItemView.ts
  5. FoldBigItemSkin.exml

参考基础item 的ts代码

第三步:初始化组件和预览的配置(注意FoldBigItemSkin.exml中的自适应高度问题,就去掉skin中的高度,在底部设置一个空的group,设定好top的值)

3.1FoldListDemoView.ts中添加 初始化List
 

    closeBtn: eui.Button;

    arrCollection: eui.ArrayCollection;

list:eui.List;

initUI():中添加:

        let self = this;



        let data = [];

        for(let i:number = 0;i<20;i++){

            data.push({name:"大Item",info:i});

        }

        self.arrCollection = new eui.ArrayCollection(data);               

        self.list.itemRenderer = FoldListBigItemView;

        self.list.dataProvider = self.arrCollection;

 

3.2在FoldListBigItemView:中添加:初始化List

     在:uiCompHandler(){}中添加:


        let self = this;

        let data = [];

        for(let i:number = 0;i<4;i++){

            data.push({name:”大Item”,info:i});

        }

        let arrCollection = new eui.ArrayCollection(data);               

        self.list.itemRenderer = FoldListSmallItemView;

        self.list.dataProvider = arrCollection;

     和程序中添加:

private list:eui.List;

 

 

第四步:制作出一个二维数组,用来配置n*n的list数据,达到每个子菜单都分配到数据的目的

4.1在:FoldListDemoView.ts中: 制作数组

initUI();添加

        //包含15个小list的大list

        let listdata = [];

        //15个小list的生成

        for(let i:number=0;i<15;i++){

            //生成一个小list

            let smallListdata = [];

            for(let j:number=0;j<5;j++){

                smallListdata.push({bigListId:i,smallListId:j});

            }

            //小list,push进,大list

             this.listdata.push({listvis:false,bigListId:i,smallList:smallListdata});

        }

 

以及之前的:

        self.arrCollection = new eui.ArrayCollection(listdata);               

        self.list.itemRenderer = FoldListBigItemView;

        self.list.dataProvider = self.arrCollection;

 

 

4.2在:FoldListBigItemView.ts中: 重新初始化子list菜单

 

删除掉之前uiComHandler()中的List初始化

在dataChanged()函数中添加:

        let self = this;

        let data = [];

        for(let i in this.data.smallList){

            data.push({bigListId:this.data.smallList[i].bigListId,smallListId:this.data.smallList[i].smallListId})

        }

        let arrCollection = new eui.ArrayCollection(data);               

        self.list.itemRenderer = FoldListSmallItemView;

        self.list.dataProvider = arrCollection;

以及在:FoldListSmallItemView.ts:

的dataChanged()函数中:

console.log("xxxxxxxxxxxxxxxxxxxxxxxxxxx",this.data.bigListId,this.data.smallListId);

 

第五步:根据每个item获得的坐标值配置点击事件,以及改变goup高度,实现折叠效果:

5.1写一个函数,只要触发了就会使得折叠效果进行变动

在FoldListDemoView.ts中:(其中的控件在exml一一对应)

其中ParamEvent后面会编写。

         /**点击了大的item,接受通知展开子菜单 */

         private updateScroller(event: ParamEvent): void {

                   let H = this.list.scrollV;//保存位置用来还原

                   //把打开的折叠回去

        if (this.listdata[event.data.bigListId].listvis) {

                            this.listdata[event.data.bigListId].listvis = false;

                   } else {

                            //折叠其余

                            for (let i: number = 0; i < 15; i++) {

                                     if (i == event.data.bigListId) {

                                               this.listdata[i].listvis = true;

                                     } else {

                                               this.listdata[i].listvis = false;

                                     }

                            }

                   }

        this.arrCollection.refresh();

                   //刷新还原位置

                   this.scroller.validateNow();

                   this.list.scrollV = H;

         }

在FoldListBigItemView.ts中:(其中的组件与exml文件相对应)

在dataChange()中添加

        //根据传过来的数据设定子List的显示与否

        if(this.data.listvis){

            this.smallGroup.height = this.list.height;

        }else{

            this.smallGroup.height = 0;

        }

5.2在大Item中的按钮编写触发这个函数的代码:

5.2.1编写ParamEvent.ts(一个可以传递data的事件类)

\src\example\event\ParamEvent.ts

class ParamEvent extends egret.Event{

         public data:any;

         public constructor(type:string, data:any=null) {

                   super(type);

                   this.data = data;

         }

}

5.2.2在EventName.ts中,注册点击事件:

添加上:

 //折叠菜单模块

public static FOLDLIST_TAPBIG: string = "100";//点击折叠菜单的大item

 

5.2.3在FoldListDemoView.ts中:(配置监听这个点击事件)

InitUI()中:

GameDispatcher.getInstance().addEventListener(EventName.FOLDLIST_TAPBIG, this.updateScroller, this);//监听大item的点击

以及在dispose()函数中加入移除:

GameDispatcher.getInstance().removeEventListener(EventName.FOLDLIST_TAPBIG, this.updateScroller, this);//监听大item的点击

 

5.2.4在FoldListBigItemView.ts中:(配置这个按钮触发事件)

在uiCompHandler()函数中:

this.itembutton.addEventListener(egret.TouchEvent.TOUCH_TAP, this.OnTouchHandler, this);

 

以及对应的:

private OnTouchHandler(): void {

        let dataObj: Object = { bigListId: this.data.bigListId};

        GameDispatcher.getInstance().dispatchEvent(new ParamEvent(EventName. FOLDLIST_TAPBIG,dataObj));

    }

5.3 注意FoldBigItemSkin.exml中:去掉group之外的显示。

所有控件全部装在一个group中:

这个group的所有属性里加入scrollEnabled="true"

<?xml version="1.0" encoding="utf-8"?>

<e:Skin class="FoldBigItemSkin" width="322"  xmlns:e="http://ns.egret.com/eui" xmlns:w="http://ns.egret.com/wing">

         <e:Group width="322" x="0" y="0" scrollEnabled="true">

                   <e:Image source="card_bg" anchorOffsetY="0" height="109" anchorOffsetX="0" width="319" scale9Grid="30,30,100,100" x="0" y="0" scaleX="1" scaleY="1"/>

                   <e:Group height="34" width="197.79" x="21.5" y="32.5" anchorOffsetX="0" scaleX="1" scaleY="1">

                            <e:Label id="titleDisplay" text="普通化肥" textColor="16777215" size="21" bold="true" horizontalCenter="-20.5" verticalCenter="3.5"/>

                            <e:Image source="icon_diamond" scaleX="0.5" scaleY="0.5" width="60" y="2" x="167.79"/>

                            <e:Image source="icon_02" x="-3" y="-5.5"/>

                   </e:Group>

                   <e:Button id="itembutton" label="B" x="228.89" y="32.5" anchorOffsetX="0" width="60" anchorOffsetY="0" height="34" scaleX="1" scaleY="1"/>

                   <e:Group id="smallGroup" width="322" x="0" anchorOffsetY="0" top="109" y="109" scaleX="1" scaleY="1">

                            <e:List id="list" width="322" x="0" y="0" blendMode="normal"/>

                   </e:Group>

         </e:Group>



</e:Skin>

 

 

5.4添加上折叠的动画

5.4.1打开:FoldListBigItemView.ts

dataChanged():函数:(去掉之前的直接赋值this.smallGroup.height)

        //根据传过来的数据设定子List的显示与否

         if (this.data.listvis != this.storelistvis) {//检测this.data.listvis是否有变动

            this.playFold(this.data.listvis);

         }

5.4.2 FoldListBigItemView.ts中增加动画函数:  

  private storelistvis: boolean = false;

private isPlaying: boolean = false;



    private playFold(dakai: boolean): void {

        let self = this;

        if (self.isPlaying == false) {

            self.isPlaying = true;

            if (dakai) {             

                egret.Tween.removeTweens(this.smallGroup);//播放前先清除之前的动画

                //this.smallGroup.height = 0;

                let tween = egret.Tween.get(this.smallGroup).to({ height: this.list.height }, 300).call(function () { self.isPlaying = false;self.storelistvis = true; });

            } else {

                egret.Tween.removeTweens(this.smallGroup);//播放前先清除之前的动画

                //this.smallGroup.height = this.list.height;

                let tween2 = egret.Tween.get(this.smallGroup).to({ height: 0 }, 300).call(function () { self.isPlaying = false;self.storelistvis = false; });

            }

        }

    }

6.运行测试