FairyGUI 超简单的UI框架

Laya使用fgui的超简单UI框架

使用场景:用于使用fgui进行layaUI开发的程序人员

整个框架分为3个模块,共有4个类:

  • FGUIManager :FGUI的管理类,继承于IUIManager 负责所有UI的打开关闭等事项
  • FUIBase :UI的管理基类,具体实现
  • IUIManager :FGUI的接口类 规定管理类的各个方法
  • UILayerType: UI 层级分类

FGUIManager管理类

    import IUIManager from "./IUIManager";
import { FUIBase } from "./FUIBase";
import GameEntry from "../../GameEntry"; /**
* @ name:FGUIManager
* @ desc:自动创建说明
* @ user:By NUOLO
* @ data: 2021-06-02 18:14
*/
export default class FGUIManager implements IUIManager {
/**
*
*/
constructor() {
this.Init();
} Init(): void {
Laya.stage.addChild(fgui.GRoot.inst.displayObject); //初始化FGUI
this.UIroot = fgui.GRoot.inst.displayObject;
this.UIroot.width = Laya.stage.width;
this.UIroot.height = Laya.stage.height;
fgui.UIConfig.packageFileExtension = "fui"; //设置导出文件的拓展名 代码默认的拓展名为fui,可能于自身导出的拓展名不同 但最好这样做因为有些平台只认这种文件名
this.UIDic = {};
} /**
* UI字典
*/
UIDic: { [name: string]: FUIBase<fgui.GComponent>}; /**
* UI的根节点
*/
private UIroot: Laya.Sprite;
/**
* 注入FUIBase
*/
RigisterUIBase(name: string, ui: FUIBase<fgui.GComponent>): void {
if (this.UIDic[name]) {
console.log(name + "::字段已存在UI界面,请勿重复添加")
return;
}
else {
this.UIDic[name] = ui;
}
} CreateOrOpenPanel(name: string, data?:new () => FUIBase<fgui.GComponent> , isCloseOther?: boolean): FUIBase<any> {
if (!this.UIroot) {
this.Init();
}
if (this.UIDic[name]) {
return this.OpenPanel(name, isCloseOther);
}
else {
let cla = new data(); if (fgui.UIPackage.addPackage(data['ResName']) == null) {
console.log('资源包未加载,将进行自动加载');
fgui.UIPackage.addPackage(data['ResName']);
} // let com = fgui.UIPackage.createObject(data['UIpackName'], data['UIName'], cla.ClassType).asCom;
let com = fgui.UIPackage.createObjectFromURL(cla.ClassType.URL,cla.ClassType).asCom ;
com.name = data['UIName'];
fgui.GRoot.inst.addChild(com);
com.makeFullScreen(); com.sortingOrder = cla.LayerType;
cla.MUI = com;
cla.UIMgr = this;
cla.AutoRigisterToUIManager();
cla.onAwake();
cla.onEnable();
return cla;
}
} OpenPanel(name: string, isCloseOther?: boolean): FUIBase<any> {
if (isCloseOther) {
for (let uiname in this.UIDic) {
this.UIDic[uiname].Close();
}
}
if (this.UIDic[name]) {
let ui = this.UIDic[name];
ui.Open();
return ui;
}
else { console.error(name + "::字段在UI字典中不存在,请检查是否有误")
return null;
}
}
ClosePanel(name: string, toOpenWindow?: string): void {
if (this.UIDic[name]) {
let ui = this.UIDic[name];
ui.Close();
if (toOpenWindow != null) {
this.OpenPanel(toOpenWindow);
}
}
else {
console.log(name + "::字段在UI字典中不存在,请检查是否有误")
}
}
CloseAllPanel(): void {
for (const key in this.UIDic) {
this.UIDic[key].Close();
}
}
GetUIPanel(name: string): any {
if (this.UIDic[name]) {
return this.UIDic[name] ;
}
else {
console.log(name + "::字段在Ui字典中不存在,请检查")
return null;
}
}
DestoryUIPanel(name: string) {
if (this.UIDic[name]) {
this.UIDic[name].Destory();
}
else {
console.log(name + "::字段在Ui字典中不存在,请检查")
}
} }

FUIBase

    import AssetData from "../../Asset/AssetData";
import Debug from "../../Debug/Debug";
import GameEntry from "../../GameEntry";
import IUIManager from "./IUIManager";
import { UILayerType } from "./UILayerType"; /**
* @ name:FUIBase
* @ desc:自动创建说明
* @ user:By NUOLO
* @ data: 2021-06-02 16:24
*/
export class FUIBase<T extends fgui.GComponent> { /**需子类设置 导出包的路径 */
public static ResName: string = "res/UIVSLoading";
/**需子类设置 图集的数量 从0 开始 */
public static AtliasCount: number = 1; public static UIName: string = "1"; //UI的名字 要存在字典中
public get UIName(): string { return FUIBase.UIName; }
public set UIName(v: string) { FUIBase.UIName = v; } /** UI的层级 默认0级为最底层 */
public LayerType: UILayerType = UILayerType.Normal; /**fgui 组件 */
private m_uiComPonent: T;
public get MUI(): T { return this.m_uiComPonent; }
public set MUI(v: T) { this.m_uiComPonent = v; } /**fgui 组件 */
public ClassType: any; /**UI管理类 */
private m_uimgr: IUIManager;
public get UIMgr(): IUIManager { return this.m_uimgr; }
public set UIMgr(v: IUIManager) { this.m_uimgr = v; } /**
* 自动注册进UIManager
*/
public AutoRigisterToUIManager() {
this.UIMgr.RigisterUIBase(this.UIName, this);
} /**
* 打开界面
*/
public Open() {
this.onEnable();
this.m_uiComPonent.visible = true; }
/**
* 关闭界面
*/
public Close() {
this.onDisable();
this.m_uiComPonent.visible = false;
} /**
* 销毁界面
*/
public Destory() {
this.m_uiComPonent.dispose();
} //#region fgui加载 /**
* 获取当前界面所对应的资源文件
* @returns
*/
public static GetLoadUIPackDic(): any[] {
let urls = [];
urls.push({ url: this.ResName + ".fui", type: Laya.Loader.BUFFER });
urls.push({ url: this.ResName + "_atlas0.png", type: Laya.Loader.IMAGE });
//加载纹理集
if (this.AtliasCount >=1) {
for (let i = 1; i <= this.AtliasCount; i++) {
urls.push({ url: this.ResName + "_atlas0_" + i + ".png", type: Laya.Loader.IMAGE });
}
}
return urls;
} /**
* 获取FGUI 二进制文件路径
* @returns 对应路径
*/
public static GetUIByte(): string {
return this.ResName + ".fui";
}
/**
* 加载完成之后 将包添加到fgui包管理中
*/
public static AddPackage() {
fgui.UIPackage.addPackage(this.ResName);
}
//#endregion //#region 功能 /**
* 获得子节点
* @param path 路径信息 s.b.v
*/
public FindChild<T extends fgui.GObject>(path: String): T {
return this.m_uiComPonent.getChildByPath(path) as T;
} /**
* 添加事件监听
* @param btn 点击按钮
* @param callback 回调
* @param args 传递数据
*/
public AddLinster(btn: fgui.GObject, callback, ...args) {
btn.onClick(this, callback, args);
} /**
* 移除事件监听
* @param btn 按钮
* @param callback 回调
*/
public RemoveLinster(btn: fgui.GObject, callback) {
btn.offClick(btn, callback);
}
//#endregion //#region 生命流程 onAwake() {} //onAwake 创建时调用
onEnable() {} //每次打开时调用,可自行拓展打开时的打开效果等功能
onDisable() {} //每次关闭时调用,可自行拓展关闭时的 所需调用的功能
//#endregion
}

IUIManager

    import { FUIBase } from "./FUIBase";

    /**
* @ name:IUIManager
* @ desc:UI管理类的接口
* @ user:By NUOLO
* @ data: 2021-06-02 16:14
*/
export default interface IUIManager { /**
* 初始化
*/
Init():void /**
* UI字典
*/
UIDic: { [name: string]: FUIBase<any> }; /**
* 注入FUIBase
*/
RigisterUIBase(name: string, ui: FUIBase<any>): void; /**
* 自动创建 或者打开 界面 注意:创建UI是异步操作的
* @param name 名字
* @param isCloseOther 是否关闭其他界面
* @param data 数据
*/
CreateOrOpenPanel(name: string, data?:any, isCloseOther?: boolean ): FUIBase<any> /**
* 打开UI界面
* @param name 要打开界面的名字
* @param isCloseOther 是否关闭其他界面 默认否
*/
OpenPanel(name: string, isCloseOther?: boolean): FUIBase<any>; /**
* 关闭UI界面
* @param name 要关闭UI界面的名字
* @param TOOpen 关闭此界面后要打开的界面的名字 默认无 不打开其他界面
*/
ClosePanel(name: string,toOpenWindow?:string): void;
/**
* 关闭所有UI界面
*/
CloseAllPanel(): void;
/**
* 根据标识符获取FUIBase
* @param name 标识符
*/
GetUIPanel(name: string):any; /**
* 销毁UIPanel
* @param name 标识符
*/
DestoryUIPanel(name: string); }

UILayerType

    /**
* @ name:UILayerType
* @ desc:UI 层级分类
* @ user:By NUOLO
* @ data: 2021-06-02 16:55
*/
export enum UILayerType {
//普通窗体
Normal=0,
//固定窗体
Fixed=20,
//弹出窗体
PopUp = 50,
//提示窗体
Tip = 40,
}

框架就分为这4个类 使用的话就每个UI界面都继承 FUIBase<具体fgui导出的UI类>

并重写 参数

如例子:

fgui 导出文件为  Package1.fui
Package1Binder.ts
UI_Component1.ts
Package1Binder.ts 新建一个ShowUI 的脚本 继承与FUIBase <UI_Component1>

示例 ShowUI类

    import { FUIBase } from "../Core/UI/FGUI/FUIBase";
import { UILayerType } from "../Core/UI/FGUI/UILayerType";
import Package1Binder from "./Package1/Package1Binder";
import UI_Component1 from "./Package1/UI_Component1"; /**
* @ name:ShowUI
* @ desc:UI的控制类
* @ user:By NUOLO
* @ data: 2021-06-09 11:00
*/
export default class ShowUI extends FUIBase <UI_Component1>{ public static ResName: string = "res/FGUI/Package1"; //路径
public static AtliasCount: number = 0; //图集数量 从0开始
public static UIName: string = "1"; //名称
constructor() {
super();
this.LayerType = UILayerType.Normal; //设置层级
this.ClassType = UI_Component1; //设置UI所对应的类,,确定好再填
Package1Binder.bindAll(); //UI绑定类
} onAwake() {
super.onAwake();
}
onEnable() {
super.onEnable();
}
onDisable() {
super.onDisable();
}
}

示例 调用方法

    onConfigLoaded(): void {
//加载IDE指定的场景
// GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
this.openFGUI();
}
openFGUI() {
let uimagr = new FGUIManager(); //初始化UI管理类 //打开界面
Laya.loader.create(ShowUI.GetLoadUIPackDic(), Laya.Handler.create(this, () => {
uimagr.CreateOrOpenPanel(ShowUI.UIName, ShowUI);
}));
}

整个调用过程都很简单,代码逻辑也很明了,自己正在使用中

如果有更好的方法和更优雅的写法,也请通过邮件联系我,共同学习一下,多谢!

个人博客地址 https://nuolo.xyz

laya fgui 超简单的UI框架的更多相关文章

  1. WPF - 简单的UI框架

    实现了一个简单的WPF应用程序UI框架 ,分享出来.界面效果图如下: 运行效果如下: 喜欢的可以下载源码参考:https://github.com/DuelWithSelf/WPFEffects 左侧 ...

  2. WPF - 简单的UI框架 - 仪表盘

    源码链接:https://github.com/DuelWithSelf/WPFEffects 参考:https://www.cnblogs.com/duel/p/duel_clock.html 更新 ...

  3. 【设计和开发一套简单自己主动化UI框架】

    !有兴趣的朋友请直接移步Github,本帖子已经不做更新,框架的详细的实现已经做了优化和代码整理,本文仅仅介绍了详细的设计思路! 目标:编写一个简单通用UI框架用于管理页面和完毕导航跳转 终于的实现效 ...

  4. 【转】发布一个基于NGUI编写的UI框架

    发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...

  5. ssh框架整合---- spring 4.0 + struts 2.3.16 + maven ss整合超简单实例

    一 . 需求 学了这么久的ssh,一直都是别人整合好的框架去写代码,自己实际动手时才发现框架配置真是很坑爹,一不小心就踏错,真是纸上得来终觉浅! 本文将记录整合struts + spring的过程 , ...

  6. (转载)基于Unity~UGUI的简单UI框架(附UIFramework源码)

    此博客跟随siki老师的课程笔记生成,感谢siki老师的辛勤付出! 此框架功能较简单,适用于学习,可以很好的锻炼我们的设计思想 框架源码地址: UIFramework litjson.dll下载地址: ...

  7. 关于几种UI框架简单总结

    最近两年多的时间先后做过几款终端程序,UI框架从MFC转向过WxWidgets,之后再转向Qt.三种框架精通远谈不上,用起来还是没什么问题. 简单聊聊三种框架的优缺点. 1.MFC 似乎作为一种饱受批 ...

  8. ASP.NET MVC搭建项目后台UI框架—5、Demo演示Controller和View的交互

    目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NE ...

  9. 如何快速体验鸿蒙全新声明式UI框架ArkUI?

    HDC2021将于10月22日在东莞松山湖正式开幕,大会将设立Codelab体验专区,超多好玩.有趣的Demo等你体验.想快速入门HarmonyOS?学习HarmonyOS新特性?以下几个Codela ...

随机推荐

  1. PHP + JQuery 实现多图上传并预览

    简述 PHP + JQuery实现 前台:将图片进行base64编码,使用ajax实现上传 后台:将base64进行解码,存储至文件夹,将文件名称入库 效果图 功能实现 html <!DOCTY ...

  2. 【Docker】5. 常用命令—镜像命令

    学习命令,官方文档千万别忘记了,不会的就到这里来查. 一.帮助命令 1.显示docker哪些命令 docker --help 另外,也可以查看具体命令的用法,比如我想知道命令docker images ...

  3. webpack 快速入门 系列 —— 实战一

    实战一 准备本篇的环境 虽然可以仅展示核心代码,但笔者认为在一个完整的环境中边看边做,举一反三,效果更佳. 这里的环境其实就是初步认识 webpack一文完整的示例,包含 webpack.devSer ...

  4. 什么是CPU缓存

    一.什么是CPU缓存 1. CPU缓存的来历 众所周知,CPU是计算机的大脑,它负责执行程序的指令,而内存负责存数据, 包括程序自身的数据.在很多年前,CPU的频率与内存总线的频率在同一层面上.内存的 ...

  5. Ubuntu 配置本地源

    Ubuntu 配置本地源 操作系统 Ubuntu 20.04.2 LTS 一.挂载 iso 到本地 mount -t iso9660 -o loop /dev/sr0 /media/cdrom //- ...

  6. 使用LUKS加密你的磁盘

    计算机数据的安全,保密性在现在的生活中显得越来越重要.随着数字化的时代的来临,越来越多的数据被数字化,特别是更多有关于我们隐私的数据在不断生成,甚至还有我们需要离线保存的密钥等.而且通常我们使用磁盘, ...

  7. vue 实现带模板的EXCEL导出

    话不多说直接上代码 1.前端(个人逻辑做了Excel导出和world导出,world导出会在下一个博客中列出) var xhr = new XMLHttpRequest() var url = win ...

  8. python字典转bytes类型字典

    python字典转bytes类型字典import base64 import json 1. a={"Vod":{"userData":"{}&quo ...

  9. Docker学习(9) Docker守护进程的配置和操作

  10. 执行Selenium后在temp目录下产生临时文件scoped_dir chrome_BITS

    环境:Windows selenium 3.141.0 Python 3.8.10 Chrome 90.0.4430.212 ChromeDriver 90.0.4430.24 最近发现执行完Sele ...