Laya1.0 UI模式

  • A+
所属分类:laya

Laya1.0 UI模式

目录

  1. 内嵌模式(默认模式)
  2. 加载模式
  3. 分离模式
  4. 使用示例
  5. 分离模式下IDE自动生成createView代码

Laya1.0的UI模式有内嵌模式,加载模式和分离模式,总共3种模式。本文将介绍各种模式的差异,并通过示例演示3种模式如何使用。

内嵌模式(默认模式)

内嵌模式是IDE默认使用的方式,这种模式下,进行UI页面的导出时,会将配置信息等内容导出为项目的代码文件。最终发布成游戏时,UI页面配置信息会全部出现在游戏的js文件中。这种模式下,由于js文件较大(因为包含了UI页面信息),会导致启动页index.html加载较慢,另外对于微信小游戏来说,也占用了小游戏本地包的体积。

加载模式

加载模式是将所有UI页面的配置信息导出为一份json文件,跟UI页面定义代码分离的一种模式。该模式下,需要先加载UI的全局json配置文件,才能在游戏中打开各个UI页面。由于分离了UI页面配置信息,js文件的体积也会相应降低,适合在微信小游戏中使用此模式。另外该模式,简单易用,不需要修改过多代码,即可从内嵌模式修改为加载模式。

分离模式

分离模式与加载模式类似,加载模式将所有UI页面配置信息导出为一份json配置文件,而分离模式,则是按UI页面分别导出json文件,并不会把所有的页面配置合并在一个json文件中。所以,分离模式最终导出的是多份json配置文件。该模式在使用时,需要先加载对应UI页面的json配置文件后,才能打开对应的UI页面。另外,此模式下,需要在UI页面创建时主动调用createView方法,而UI代码又是自动生成的,所以使用起来比较麻烦,需要通过修改IDE相关代码才能实现自动添加createView方法。此模式相较加载模式的优点是,没打开的页面不进行加载,也减少了一定的内存,而且首次加载需要的流量也更小,毕竟只加载了需要的UI配置而不是全部UI配置。缺点,需要修改IDE代码实现自动化,另外可能还需要修改相应的项目代码,总的来说比较麻烦。

使用示例

下面将使用layaIDE 1.7.21进行演示。

建立测试用项目

  • 新建as3的空UI项目

    Laya1.0 UI模式

  • 快捷键Alt + w切换到编辑模式

  • 右键新建UI页面a

    Laya1.0 UI模式

    Laya1.0 UI模式

  • 打开a.ui页面,并切换到代码模式,修改代码如下:

    <View width="600" sceneColor="#000000" height="400" editorInfo="compId=1">
        <Button y="197" x="74" width="450" var="btnA" skin="comp/button.png" sizeGrid="6,15,9,15" labelSize="60" label="跳转到B" height="166" editorInfo="compId=2"/>
        <Label y="35" x="86" width="428" text="我是A页面" styleSkin="comp/label.png" height="92" fontSize="80" color="#f8f0ef" bold="true" editorInfo="compId=3"/>
    </View>
    

    Laya1.0 UI模式

  • 切换回视图模式,并且按ctrl+s保存UI修改。

    Laya1.0 UI模式

  • 最后a页面如下图所示

    Laya1.0 UI模式

  • 创建多一个b.ui页面,不过我们这里尝试将b.ui文件置于文件夹test

    Laya1.0 UI模式

  • 打开b.ui页面,并切换到代码模式,修改代码如下:

    <View width="600" sceneColor="#000000" height="400" editorInfo="compId=1">
        <Button y="197" x="74" width="450" var="btnB" skin="comp/button.png" sizeGrid="6,15,9,15" labelStrokeColor="#f61915" labelStroke="2" labelSize="60" label="跳转到A" height="166" editorInfo="compId=2"/>
        <Label y="49" x="86" width="428" text="我是B页面" styleSkin="comp/label.png" strokeColor="#f31815" stroke="1" height="92" fontSize="80" color="#91a5f3" bold="true" editorInfo="compId=3"/>
    </View>
    
  • 切换回视图模式,并且按ctrl+s保存UI修改,最后b.ui页面如下

    Laya1.0 UI模式

内嵌模式演示

  • 快捷键ctrl+F12清理并导出UI代码

  • 快捷键Alt+Q切换到代码模式

    Laya1.0 UI模式

    我们可以看到aUI.as文件内容如下:

    /**Created by the LayaAirIDE,do not modify.*/
    package ui {
        import laya.ui.*;
        import laya.display.*; 
    
        public class aUI extends View {
            public var btnA:Button;
    
            public static var uiView:Object =/*[STATIC SAFE]*/{"type":"View","props":{"width":600,"height":400},"child":[{"type":"Button","props":{"y":197,"x":74,"width":450,"var":"btnA","skin":"comp/button.png","sizeGrid":"6,15,9,15","labelSize":60,"label":"跳转到B","height":166}},{"type":"Label","props":{"y":35,"x":86,"width":428,"text":"我是A页面","styleSkin":"comp/label.png","height":92,"fontSize":80,"color":"#f8f0ef","bold":true}}]};
            override protected function createChildren():void {
                super.createChildren();
                createView(uiView);
    
            }
    
        }
    }
    

    从代码可以看出,类aUI不仅包含了按钮btnA的声明,还包含了ui页面大小,字体,按钮颜色文字等各种信息。
    以上就是内嵌模式生成的UI类,相对来说比较臃肿。

  • 我们写个简单代码来使用aUI和bUI。修改LayaSample.as代码如下:

    package {
        import laya.events.Event;
        import laya.ui.View;
        import laya.utils.Handler;
        import laya.webgl.WebGL;
    
        import ui.aUI;
        import ui.test.bUI;
        import laya.net.Loader;
    
        public class LayaSample {
    
            private var newUI:*;
    
            public function LayaSample() {
                //初始化引擎
                Laya.init(0, 0,WebGL);
                Laya.stage.scaleMode = "full";
                //加载图集
                Laya.loader.load(["res/atlas/comp.atlas"], Handler.create(this, onLoaded));
    
            }       
    
            //显示UI切换界面的通用函数
            private function showUI(UIname:*,delUI:*=null):void
            {
                if(delUI != null)
                    delUI.removeSelf();//删除指定UI
                //实例化新的UI
                newUI = new UIname();
                //添加UI在舞台
                Laya.stage.addChild(newUI);
            }
    
            //图集加载后回调
            private function onLoaded():void
            {
                showUI(aUI);
                //监听按钮btnA的点击事件,触发后处理
                newUI.btnA.on(Event.CLICK, this, showB);
            }
    
            //显示B页
            private function showB():void
            {
                showUI(bUI,newUI)
                //监听按钮btnB的点击事件,触发后处理
                newUI.btnB.on(Event.CLICK, this, showA);
            }
    
            //显示A页
            private function showA():void
            {
                showUI(aUI,newUI)
                //监听按钮btnA的点击事件,触发后处理
                newUI.btnA.on(Event.CLICK, this, showB);
            }
        }
    }
    
  • 快捷键F5编译运行程序,可看到如下图,有A,B两个页面点击后相互跳转。

    Laya1.0 UI模式

    Laya1.0 UI模式

  • 内嵌模式下,当UI页面使用的资源文件res/atlas/comp.atlas加载完成后,可以直接对页面进行操作,不需要额外编写代码。

加载模式演示

  • 快捷键Alt+w再次切换到编辑模式,使用F9打开项目设置面板。

    Laya1.0 UI模式

    并做如上图所示修改,修改UI模式加载模式,修改加载UI发布目录bin/h5/ui.json,并点击确定按钮。这样我们再重新清理导出UI,所有的UI配置就会写入到ui.json文件中。

  • 快捷键ctrl+F12清理并导出UI。

  • 快捷键Alt+Q切换到代码模式,并重新打开aUI.as文件。

    我们可以看到代码如下:

    /**Created by the LayaAirIDE,do not modify.*/
    package ui {
        import laya.ui.*;
        import laya.display.*; 
    
        public class aUI extends View {
            public var btnA:Button;
    
            override protected function createChildren():void {
                super.createChildren();
                loadUI("a");
    
            }
    
        }
    }
    

    很明显,相较于内嵌模式,代码量减少了,减少了UI页面相关的配置信息。那配置信息去哪里了呢?

  • 快捷键ctrl+P并输入ui.json打开ui.json文件。

    Laya1.0 UI模式

    看到ui.json内容如下:

    {"a":{"type":"View","props":{"width":600,"height":400},"child":[{"type":"Button","props":{"y":197,"x":74,"width":450,"var":"btnA","skin":"comp/button.png","sizeGrid":"6,15,9,15","labelSize":60,"label":"跳转到B","height":166}},{"type":"Label","props":{"y":35,"x":86,"width":428,"text":"我是A页面","styleSkin":"comp/label.png","height":92,"fontSize":80,"color":"#f8f0ef","bold":true}}]},"test/b":{"type":"View","props":{"width":600,"height":400},"child":[{"type":"Button","props":{"y":197,"x":74,"width":450,"var":"btnB","skin":"comp/button.png","sizeGrid":"6,15,9,15","labelStrokeColor":"#f61915","labelStroke":2,"labelSize":60,"label":"跳转到A","height":166}},{"type":"Label","props":{"y":49,"x":86,"width":428,"text":"我是B页面","styleSkin":"comp/label.png","strokeColor":"#f31815","stroke":1,"height":92,"fontSize":80,"color":"#91a5f3","bold":true}}]}}
    

    可以看到ui.json包含了UI页面a和b的页面配置信息。

  • 修改加载代码。

    由于页面配置信息被分离开来,所以我们需要先加载UI页面的配置文件ui.json,之后才能对UI页面进行操纵。

    修改函数LayaSample和函数onLoaded如下:

    public function LayaSample() {
        //初始化引擎
        Laya.init(0, 0,WebGL);
        Laya.stage.scaleMode = "full";
        //加载图集
        // Laya.loader.load(["res/atlas/comp.atlas"], Handler.create(this, onLoaded));
    
        Laya.loader.load([{ url: "res/atlas/comp.atlas", type: Loader.ATLAS },{ url: "ui.json", type: Loader.JSON }], Handler.create(this, this.onLoaded));
    }
    
    private function onLoaded():void
    {
        View.uiMap = Laya.loader.getRes("ui.json");
    
        showUI(aUI);
        //监听按钮btnA的点击事件,触发后处理
        newUI.btnA.on(Event.CLICK, this, showB);
    }
    
  • 快捷键F5,编译运行程序

    Laya1.0 UI模式

    可以看到程序正常运行,并且加载了ui.json文件。

  • 加载模式步骤总结

    总的来说,加载模式需要以下几个步骤:

    1. 导出UI代码的时候以加载模式进行导出。
    2. 先加载所有UI的配置文件ui.json
    3. View.uiMap进行赋值,即View.uiMap = Laya.loader.getRes("ui.json");

分离模式演示

  • 快捷键Alt+w再次切换到编辑模式,使用F9打开项目设置面板。

    Laya1.0 UI模式

    并做如上图所示修改,修改UI模式加载模式,修改加载UI发布目录bin/h5/ui,并点击确定按钮。这样我们再重新清理导出UI,所有的UI配置就会分别写入到bin/h5/ui文件夹中。

  • 快捷键ctrl+F12清理并导出UI。

  • 快捷键Alt+Q切换到代码模式,并重新打开aUI.as文件。

    我们可以看到代码如下:

    /**Created by the LayaAirIDE,do not modify.*/
    package ui {
        import laya.ui.*;
        import laya.display.*; 
    
        public class aUI extends View {
            public var btnA:Button;
    
            override protected function createChildren():void {
                super.createChildren();
                loadUI("a");
    
            }
    
        }
    }
    

    此时,我们发现,aUI.as的代码与加载模式下的代码是一样的。

    事实上,这代码仍需修改才能运行,需要主动调用createView函数

  • aUI.as代码,如下:
    /**Created by the LayaAirIDE,do not modify.*/
    package ui {
        import laya.ui.*;
        import laya.display.*; 
    
        public class aUI extends View {
            public var btnA:Button;
    
            override protected function createChildren():void {
                super.createChildren();
                this.createView(Laya.loader.getRes("ui/a.json"));
                loadUI("a");
    
            }
    
        }
    }
    

    从上可以看到增加了this.createView(Laya.loader.getRes("ui/a.json"));这一行代码

  • bUI.as代码,如下:

    /**Created by the LayaAirIDE,do not modify.*/
    package ui.test {
        import laya.ui.*;
        import laya.display.*; 
    
        public class bUI extends View {
            public var btnB:Button;
    
            override protected function createChildren():void {
                super.createChildren();
                this.createView(Laya.loader.getRes("ui/test/b.json"));
                loadUI("test/b");
    
            }
    
        }
    }
    

    从上可以看到增加了this.createView(Laya.loader.getRes("ui/test/b.json"));这一行代码

  • 修改LayaSample.as代码,使其采用分离加载的模式。

    修改LayaSample函数如下:

    public function LayaSample() {
        //初始化引擎
        Laya.init(0, 0,WebGL);
        Laya.stage.scaleMode = "full";
        //加载图集
        Laya.loader.load(["res/atlas/comp.atlas"], Handler.create(this, onLoaded));
    
    }
    

    修改onLoaded函数如下:

    private function onLoaded():void
    {
        Laya.loader.load([{ url: "ui/a.json", type: Loader.JSON }], Handler.create(this, function():void {
            showUI(aUI);
            //监听按钮btnA的点击事件,触发后处理
            newUI.btnA.on(Event.CLICK, this, showB);
        }));
    }
    

    修改showB函数如下:

    private function showB():void
    {
        Laya.loader.load([{ url: "ui/test/b.json", type: Loader.JSON }], Handler.create(this, function():void {
            showUI(bUI,newUI)
            //监听按钮btnB的点击事件,触发后处理
            newUI.btnB.on(Event.CLICK, this, showA);
        }));
    }
    

    修改showA函数如下:

    private function showA():void
    {
        Laya.loader.load([{ url: "ui/a.json", type: Loader.JSON }], Handler.create(this, function():void {
            showUI(aUI,newUI)
            //监听按钮btnA的点击事件,触发后处理
            newUI.btnA.on(Event.CLICK, this, showB);
        }));
    }
    
  • 快捷键F5编译运行程序

    可以看到先加载了a.json配置。

    Laya1.0 UI模式

    在点击了跳转后,再加载了b.json配置。

    Laya1.0 UI模式

    到这里,分离模式就能正常运作了。

  • 分离模式步骤总结:

    总的来说,分离模式也是三个步骤:

    1. 导出UI代码的时候以分离模式进行导出。
    2. 在打开对应的UI界面时,先加载对应UI界面的json配置文件。
    3. 在UI类中调用createView方法,来将配置与UI关联。

分离模式下IDE自动生成createView代码

从上面的分离模式演示示例中,我们是在aUI.asbUI.as文件中编码this.createView(Laya.loader.getRes("ui/a.json"));this.createView(Laya.loader.getRes("ui/test/b.json"));。但这种做法,是不正确的,因为aUI.asbUI.as可能在无意中被IDE修改。

那怎样才能做到在UI类文件中自动添加如上代码呢?

可以考虑以下两个方案:

1. 写一个额外的脚本,对生成后的UI类代码进行处理,自动往UI类代码添加createView调用。

2. 让IDE生成代码的时候,自动帮我们加上createView调用。

由于第一个方案相当于是2次处理,虽然在某些时候很方便,但是需要在生成代码后,运行多一次额外脚本,稍显麻烦,所以下面我采用第二种方案,直接修改IDE生成代码的脚本,实现我们的功能。

修改IDE的UI导出生成代码

我的layaAir IDE安装路径是E:\H5\LayaIDE,以下是基于我这个路径来讲解的。

Laya1.0 UI模式

  • 新增分离模式代码模板

    打开文件夹E:\H5\LayaIDE\resources\app\out\vs\layaEditor\codeTemplate,并拷贝asCodeTpl.txt.load重命名为asCodeTpl.txt.fenli

    Laya1.0 UI模式

    并修改asCodeTpl.txt.fenli代码如下:

    /**Created by the LayaAirIDE,do not modify.*/
    package {!pack!} {
    {!imports!}
        public class {!className!} extends {!classType!} {
    {!vars!}
            override protected function createChildren():void {
    {!viewClassMap!}            super.createChildren();
                this.createView(Laya.loader.getRes("ui/{!uiPath!}.json"));
                loadUI("{!uiPath!}");
    {!dataBinds!}
            }
    {!addCodes!}
        }
    }
    

    Laya1.0 UI模式

  • 修改IDE生成UI的js代码

    打开E:\H5\LayaIDE\resources\app\out\vs\layaEditor\h5目录,并打开layabuilder.max.js文件

    Laya1.0 UI模式

    在如下图所示位置,新增代码CodeTplManager.asCodeTplFenli=FileManager.readTxtFile(FileManager.getAppPath(Paths.ASCodeTemplate+".fenli"));

    Laya1.0 UI模式

    这行代码的作用就是将CodeTplManager.asCodeTplFenli指向我们刚才的模板文件。

    然后再修改CodeTplManager.getCodeTpl函数,当选择的是分离模式时,使用我们的模板文件。只需在如下图的地方将原先的代码

    CodeTplManager.getCodeTpl=function(codeType,isPreset,isLoad,isEfc){
            (isEfc===void 0)&& (isEfc=false);
            if(isLoad){
                CodeTplManager.setCodeTpls("Load");
                }else{
                CodeTplManager.setCodeTpls("NoLoad");
            };
            var tplStr;
            codeType=Math.ceil(codeType);
            switch(codeType){
                case 0:
                    tplStr=CodeTplManager.asCodeTpl;
    
                    if(isEfc){
                        tplStr=CodeTplManager.asCodeTplEfc;
                    }
                    else
                    if(isPreset){
                        tplStr=CodeTplManager.asCodeTplPst;
                    }
                    break ;
                case 2:
    

    改成

    CodeTplManager.getCodeTpl=function(codeType,isPreset,isLoad,isEfc,pageExportType){
            (isEfc===void 0)&& (isEfc=false);
            (pageExportType===void 0)&& (pageExportType=PageExportType.INCODE);
            if(isLoad){
                CodeTplManager.setCodeTpls("Load");
                }else{
                CodeTplManager.setCodeTpls("NoLoad");
            };
            var tplStr;
            codeType=Math.ceil(codeType);
            switch(codeType){
                case 0:
                    if (pageExportType == PageExportType.LOAD_ONE) {
                        // 分离模式使用我们自定义的模板
                        tplStr=CodeTplManager.asCodeTplFenli;
                    } else {
                        tplStr=CodeTplManager.asCodeTpl;
                    }
    
                    if(isEfc){
                        tplStr=CodeTplManager.asCodeTplEfc;
                    }
                    else
                    if(isPreset){
                        tplStr=CodeTplManager.asCodeTplPst;
                    }
                    break ;
                case 2:
    

    Laya1.0 UI模式

    再修改CodeManager.objToUI中调用CodeTplManager.getCodeTpl方法的地方。

            var tplStr;
            tplStr=CodeTplManager.getCodeTpl(ProjectSetting.codeType,isPreset,PageExportType.isLoadType(pageExportType),isEfc);
            str=CodeManager.createExportCode(tplStr,classObj);
            return str;
        }
    

    改成

            var tplStr;
            tplStr=CodeTplManager.getCodeTpl(ProjectSetting.codeType,isPreset,PageExportType.isLoadType(pageExportType),isEfc,pageExportType);
            str=CodeManager.createExportCode(tplStr,classObj);
            return str;
        }
    

    即可。

    Laya1.0 UI模式

  • 重启IDE(或者刷新编辑器)

    Laya1.0 UI模式

  • 快捷键Alt+w再次切换到编辑模式,然后快捷键ctrl+F12清理并导出UI。

    我们可以看到我们的代码this.createView(Laya.loader.getRes("ui/a.json"));this.createView(Laya.loader.getRes("ui/test/b.json"));没有被移除掉。

我们也可以将这两行代码删除,然后再运行一次ctrl+F12清理并导出UI。会发送可以正常生成含createView调用的代码,即表示我们修改IDE代码成功了。至此,IDE自动生成带createView调用的演示就结束了。

百分购

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: