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. 四、postman关联、参数化

    一.postman关联 在实际接口测试中,后一个接口要用到前面接口返回的结果,从而让后面的接口能够正常运行,这个过程的实现成为关联 如上图通过新版本或者老版本的语法把获取的变量access_token ...

  2. Hive企业级性能优化

    Hive作为大数据平台举足轻重的框架,以其稳定性和简单易用性也成为当前构建企业级数据仓库时使用最多的框架之一. 但是如果我们只局限于会使用Hive,而不考虑性能问题,就难搭建出一个完美的数仓,所以Hi ...

  3. Java中浮点数的坑

    基本数据类型 浮点数存在误差 浮点数有一个需要特别注意的点就是浮点数是有误差的,比如以下这段代码你觉得输出的什么结果: public class Demo { public static void m ...

  4. Pytorch_Part7_模型使用

    VisualPytorch beta发布了! 功能概述:通过可视化拖拽网络层方式搭建模型,可选择不同数据集.损失函数.优化器生成可运行pytorch代码 扩展功能:1. 模型搭建支持模块的嵌套:2. ...

  5. Form-OCR & CSDNAPP初体验

    项目 内容 课程:北航2020春软件工程 博客园班级博客 作业:阅读并撰写博客回答问题 软件案例分析 我在这个课程的目标是 全面地评价一个软件 这个作业在哪个具体方面帮助我实现目标 明确软件开发过程中 ...

  6. (Dubbo架构)基于MDC+Filter的跨应用分布式日志追踪解决方案

    在单体应用中,日志追踪通常的解决方案是给日志添加 tranID(追踪ID),生成规则因系统而异,大致效果如下: 查询时只要使用 grep 命令进行追踪id筛选即可查到此次调用链中所有日志,但是在 du ...

  7. [bug] mysql 忘记密码

    参考 https://www.cnblogs.com/black-fact/p/11613361.html

  8. 【转载】有图 KVM折腾记..

    KVM折腾记...https://lengjibo.github.io/KVM%E6%8A%98%E8%85%BE%E8%AE%B0/  Veröffentlicht am 2018-09-20 |  ...

  9. tar解压某个目录 tar解压某个指定的文件或者文件夹

    tar解压某个目录 tar解压某个指定的文件或者文件夹 发布时间:2017-05-30 来源:服务器之家   1. 先查看压缩文档中有那些文件,如果都不清楚文件内容,然后就直接解压,这个是不可能的 使 ...

  10. mitogen附带文件到远程主机

    #!/usr/bin/env python # import mitogen.master import mitogen.select import subprocess import logging ...