26.PureMVC的显隐面板Command

  1. 26.PureMVC框架-显隐面板命令
    1. 26.1 知识点
      1. 创建显示命令脚本,继承SimpleCommand。
      2. 在NewMainViewMediator要添加外部设置View的方法。设置给ViewComponent 。然后给传进来的View中的控件添加监听。等一下显示面板命令要使用。
      3. 同理,在NewRoleViewMediator要添加外部设置View的方法。设置给ViewComponent 。然后给传进来的View中的控件添加监听。等一下显示面板命令要使用。
      4. 显示命令脚本中重写Execute方法。Execute()方法从传入的notification中获取面板的名称。然后,它根据名称检查是否已经为该面板创建了中介器(Mediator)。如果没有,它就会注册一个新的中介器到Facade中。接着,命令会加载面板预设体并将其实例化。如果视图组件尚未与中介器相关联,则将其关联在一起。之后会在这里进行更新通知逻辑。如果面板已经存在,则不需要再重复上述步骤。
      5. 同理创建隐藏面板脚本继承SimpleCommand。重写了Execute()方法,首先调用了base.Execute(notification)方法,以执行基类的Execute()方法。然后,从传入的notification中获取到一个Mediator对象,该Mediator对象代表了需要隐藏的面板。接下来,通过检查Mediator对象是否为空,并且其中的ViewComponent是否存在,判断面板是否已经创建并显示在场景中。如果满足条件,表示面板存在,那么将直接使用GameObject.Destroy()函数删除面板对象,并将Mediator中的ViewComponent置空。
      6. 在GameFacade游戏外观脚本中对显示隐藏命令和通知进行绑定。
      7. 测试类中添加显示隐藏主面板逻辑
    2. 26.2 知识点代码
      1. ShowPanelCommand
      2. HidePanelCommand
      3. NewMainViewMediator
      4. NewRoleViewMediator
      5. GameFacade
      6. Main

26.PureMVC框架-显隐面板命令


26.1 知识点

创建显示命令脚本,继承SimpleCommand。

public class ShowPanelCommand : SimpleCommand
{
}

在NewMainViewMediator要添加外部设置View的方法。设置给ViewComponent 。然后给传进来的View中的控件添加监听。等一下显示面板命令要使用。

public void SetView(NewMainView view)
{
    ViewComponent = view;
    view.btnRole.onClick.AddListener(() =>
    {
        SendNotification(PureNotification.SHOW_PANEL, "RolePanel");
    });
}

同理,在NewRoleViewMediator要添加外部设置View的方法。设置给ViewComponent 。然后给传进来的View中的控件添加监听。等一下显示面板命令要使用。

public void SetView(NewRoleView view)
{
    ViewComponent = view;
    //关闭按钮 事件监听
    view.btnClose.onClick.AddListener(() =>
    {
        SendNotification(PureNotification.HIDE_PANEL, this);
    });
    
    //升级按钮监听
    view.btnLevUp.onClick.AddListener(()=>
    {
        //去升级
        //去通知升级
        SendNotification(PureNotification.LEV_UP);
    });
}

显示命令脚本中重写Execute方法。Execute()方法从传入的notification中获取面板的名称。然后,它根据名称检查是否已经为该面板创建了中介器(Mediator)。如果没有,它就会注册一个新的中介器到Facade中。接着,命令会加载面板预设体并将其实例化。如果视图组件尚未与中介器相关联,则将其关联在一起。之后会在这里进行更新通知逻辑。如果面板已经存在,则不需要再重复上述步骤。

public override void Execute(INotification notification)
{
    base.Execute(notification);
    //写面板创建的逻辑 
    string panelName = notification.Body.ToString();
    
    switch(panelName)
    {
        case "MainPanel":
            //显示面板相关内容
            
            //如果要使用Mediator 一定也要在Facade中去注册
            //command、proxy都是一样的 要用 就要注册
            //可以在命令 中 直接使用Facade代表的就是唯一的 Facade
            
            //判断如果没有mediator就去new一个 
            if( !Facade.HasMediator(NewMainViewMediator.NAME) )
            {
                Facade.RegisterMediator(new NewMainViewMediator());
            }
            //有mediator了 下一步 就是去创建界面 创建预设体 
            
            //Facade 得到Mediator的方法
            NewMainViewMediator mm = Facade.RetrieveMediator(NewMainViewMediator.NAME) as NewMainViewMediator;
            //实例化面板对象
            if (mm.ViewComponent == null)
            {
                GameObject res = Resources.Load<GameObject>("BaseFramework/UI/UGUI/PureMVC/MainPanel");
                GameObject obj = GameObject.Instantiate(res);
                //设置它的父对象 为Canvas
                obj.transform.SetParent(GameObject.Find("UGUICanvas").transform, false);
                //得到预设体上的 view脚本 关联到 mediator上
                mm.SetView(obj.GetComponent<NewMainView>());
            }
            //往往现实了面板后 需要在这里进行第一次更新
            //需要把 数据一起通过参数 传出去
            
            break;
        case "RolePanel":
            //判断如果没有mediator就去new一个 
            if (!Facade.HasMediator(NewRoleViewMediator.NAME))
            {
                Facade.RegisterMediator(new NewRoleViewMediator());
            }
            //有mediator了 下一步 就是去创建界面 创建预设体 
            
            //Facade 得到Mediator的方法
            NewRoleViewMediator rm = Facade.RetrieveMediator(NewRoleViewMediator.NAME) as NewRoleViewMediator;
            //实例化面板对象
            if (rm.ViewComponent == null)
            {
                GameObject res = Resources.Load<GameObject>("BaseFramework/UI/UGUI/PureMVC/RolePanel");
                GameObject obj = GameObject.Instantiate(res);
                //设置它的父对象 为Canvas
                obj.transform.SetParent(GameObject.Find("UGUICanvas").transform, false);
                //得到预设体上的 view脚本 关联到 mediator上
                rm.SetView(obj.GetComponent<NewRoleView>());
            }
            break;
    }
}

同理创建隐藏面板脚本继承SimpleCommand。重写了Execute()方法,首先调用了base.Execute(notification)方法,以执行基类的Execute()方法。然后,从传入的notification中获取到一个Mediator对象,该Mediator对象代表了需要隐藏的面板。接下来,通过检查Mediator对象是否为空,并且其中的ViewComponent是否存在,判断面板是否已经创建并显示在场景中。如果满足条件,表示面板存在,那么将直接使用GameObject.Destroy()函数删除面板对象,并将Mediator中的ViewComponent置空。

public class HidePanelCommand : SimpleCommand
{
    public override void Execute(INotification notification)
    {
        base.Execute(notification);
        //隐藏的目的
        //得到 mediator 再得到 mediator中的 view 然后去要不删除 要不 设置显隐
        //得到传入的 mediator
        Mediator m = notification.Body as Mediator;
        
        if( m != null && m.ViewComponent != null )
        {
            //直接删除场景上的面板对象
            GameObject.Destroy((m.ViewComponent as MonoBehaviour).gameObject);
            //删了后 一定要置空
            m.ViewComponent = null;
        }
    }
}

在GameFacade游戏外观脚本中对显示隐藏命令和通知进行绑定。

/// <summary>
/// 3.初始化 控制层相关的内容
/// </summary>
protected override void InitializeController()
{
    base.InitializeController();
    //这里面要写一些 关于 命令和通知 绑定的逻辑
    RegisterCommand(PureNotification.START_UP, () =>
    {
        return new StartUpCommand();
    });
    
    RegisterCommand(PureNotification.SHOW_PANEL, () =>
    {
        return new ShowPanelCommand();
    });
    
    RegisterCommand(PureNotification.HIDE_PANEL, () =>
    {
        return new HidePanelCommand();
    });
    
}

测试类中添加显示隐藏主面板逻辑

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour
{
    void Start()
    {
        GameFacade.Instance.StartUp();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.M))
        {
            //显示主面板
            GameFacade.Instance.SendNotification(PureNotification.SHOW_PANEL, "MainPanel");
        }
        else if (Input.GetKeyDown(KeyCode.N))
        {
            //隐藏主面板
            GameFacade.Instance.SendNotification(PureNotification.HIDE_PANEL, GameFacade.Instance.RetrieveMediator(NewMainViewMediator.NAME));
        }
    }
}

26.2 知识点代码

ShowPanelCommand

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ShowPanelCommand : SimpleCommand
{
    public override void Execute(INotification notification)
    {
        base.Execute(notification);
        //写面板创建的逻辑 
        string panelName = notification.Body.ToString();

        switch(panelName)
        {
            case "MainPanel":
                //显示面板相关内容

                //如果要使用Mediator 一定也要在Facade中去注册
                //command、proxy都是一样的 要用 就要注册
                //可以在命令 中 直接使用Facade代表的就是唯一的 Facade

                //判断如果没有mediator就去new一个 
                if( !Facade.HasMediator(NewMainViewMediator.NAME) )
                {
                    Facade.RegisterMediator(new NewMainViewMediator());
                }
                //有mediator了 下一步 就是去创建界面 创建预设体 

                //Facade 得到Mediator的方法
                NewMainViewMediator mm = Facade.RetrieveMediator(NewMainViewMediator.NAME) as NewMainViewMediator;
                //实例化面板对象
                if (mm.ViewComponent == null)
                {
                    GameObject res = Resources.Load<GameObject>("BaseFramework/UI/UGUI/PureMVC/MainPanel");
                    GameObject obj = GameObject.Instantiate(res);
                    //设置它的父对象 为Canvas
                    obj.transform.SetParent(GameObject.Find("UGUICanvas").transform, false);
                    //得到预设体上的 view脚本 关联到 mediator上
                    mm.SetView(obj.GetComponent<NewMainView>());
                }
                //往往现实了面板后 需要在这里进行第一次更新
                //需要把 数据一起通过参数 传出去

                break;
            case "RolePanel":
                //判断如果没有mediator就去new一个 
                if (!Facade.HasMediator(NewRoleViewMediator.NAME))
                {
                    Facade.RegisterMediator(new NewRoleViewMediator());
                }
                //有mediator了 下一步 就是去创建界面 创建预设体 

                //Facade 得到Mediator的方法
                NewRoleViewMediator rm = Facade.RetrieveMediator(NewRoleViewMediator.NAME) as NewRoleViewMediator;
                //实例化面板对象
                if (rm.ViewComponent == null)
                {
                    GameObject res = Resources.Load<GameObject>("BaseFramework/UI/UGUI/PureMVC/RolePanel");
                    GameObject obj = GameObject.Instantiate(res);
                    //设置它的父对象 为Canvas
                    obj.transform.SetParent(GameObject.Find("UGUICanvas").transform, false);
                    //得到预设体上的 view脚本 关联到 mediator上
                    rm.SetView(obj.GetComponent<NewRoleView>());
                }
                break;
        }
    }
}

HidePanelCommand

using PureMVC.Interfaces;
using PureMVC.Patterns.Command;
using PureMVC.Patterns.Mediator;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class HidePanelCommand : SimpleCommand
{
    public override void Execute(INotification notification)
    {
        base.Execute(notification);
        //隐藏的目的
        //得到 mediator 再得到 mediator中的 view 然后去要不删除 要不 设置显隐
        //得到传入的 mediator
        Mediator m = notification.Body as Mediator;

        if( m != null && m.ViewComponent != null )
        {
            //直接删除场景上的面板对象
            GameObject.Destroy((m.ViewComponent as MonoBehaviour).gameObject);
            //删了后 一定要置空
            m.ViewComponent = null;
        }
    }
}

NewMainViewMediator

using PureMVC.Interfaces;
using PureMVC.Patterns.Mediator;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//套路写法

//1.继承PureMVC中的Mediator脚本 
public class NewMainViewMediator : Mediator
{

    //2.写构造函数
    public static new string NAME = "NewMainViewMediator";

    public NewMainViewMediator() : base(NewMainViewMediator.NAME)
    {
        //这里面可以去创建界面预设体等等的逻辑
        //但是界面显示应该是触发的控制的 比如按键按下或者点击按钮
        //而且创建界面的代码 重复性比较高 之后在别的地方写
    }

    public void SetView(NewMainView view)
    {
        ViewComponent = view;
        view.btnRole.onClick.AddListener(() =>
        {
            SendNotification(PureNotification.SHOW_PANEL, "RolePanel");
        });
    }

    //3.重写监听通知的方法
    public override string[] ListNotificationInterests()
    {
        //这是一个PureMVC的规则
        //就是你需要监听哪些通知 那就在这里把通知们通过字符串数组的形式返回出去
        //PureMVC就会帮助我们监听这些通知 
        // 类似于 通过事件名 注册事件监听
        return new string[]{
            PureNotification.UPDATE_PLAYER_INFO,
        };
    }

    //4.重写处理通知的方法
    public override void HandleNotification(INotification notification)
    {
        //INotification 对象 里面包含两个队我们来说 重要的参数
        //1.通知名 notification.Name 我们根据这个名字 来做对应的处理
        //2.通知包含的信息 notification.Body 可以理解为通知参数 可以进行as转换

        //ViewComponent代表着实际面板对象
        switch (notification.Name)
        {
            case PureNotification.UPDATE_PLAYER_INFO:
                //收到 更新通知的时候 做处理 
                if (ViewComponent != null)
                {
                    (ViewComponent as NewMainView).UpdateInfo(notification.Body as PlayerDataObj);
                }
                break;
        }
    }

    //5.可选:重写注册时的方法
    public override void OnRegister()
    {
        base.OnRegister();
        //初始化一些内容
    }
}

NewRoleViewMediator

using PureMVC.Interfaces;
using PureMVC.Patterns.Mediator;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//套路写法
//1.继承PureMVC中的Mediator脚本 
public class NewRoleViewMediator : Mediator
{
    public static new string NAME = "NewRoleViewMediator";


    //2.写构造函数
    public NewRoleViewMediator():base(NAME)
    {

    }

    public void SetView(NewRoleView view)
    {
        ViewComponent = view;
        //关闭按钮 事件监听
        view.btnClose.onClick.AddListener(() =>
        {
            SendNotification(PureNotification.HIDE_PANEL, this);
        });

        //升级按钮监听
        view.btnLevUp.onClick.AddListener(()=>
        {
            //去升级
            //去通知升级
            SendNotification(PureNotification.LEV_UP);
        });
    }

    //3.重写监听通知的方法
    public override string[] ListNotificationInterests()
    {
        return new string[] {
            PureNotification.UPDATE_PLAYER_INFO,
            //以后你还关心别的通知 就在这后面通过逗号连接 加起来就行了
        };
    }


    //4.重写处理通知的方法
    public override void HandleNotification(INotification notification)
    {
        //INotification 对象 里面包含两个队我们来说 重要的参数
        //1.通知名 我们根据这个名字 来做对应的处理
        //2.通知包含的信息 
        switch (notification.Name)
        {
            case PureNotification.UPDATE_PLAYER_INFO:
                //玩家数据更新 逻辑处理
                if(ViewComponent != null)
                {
                    (ViewComponent as NewRoleView).UpdateInfo(notification.Body as PlayerDataObj);
                }
                break;
        }
    }
}

GameFacade

using PureMVC.Interfaces;
using PureMVC.Patterns.Facade;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//1.继承PureMVC中Facade脚本
public class GameFacade : Facade
{
    //2.为了方便我们使用Facade 需要自己写一个单例模式的属性
    public static GameFacade Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new GameFacade();
            }
            return instance as GameFacade;
        }
    }

    /// <summary>
    /// 3.初始化 控制层相关的内容
    /// </summary>
    protected override void InitializeController()
    {
        base.InitializeController();
        //这里面要写一些 关于 命令和通知 绑定的逻辑
        RegisterCommand(PureNotification.START_UP, () =>
        {
            return new StartUpCommand();
        });

        RegisterCommand(PureNotification.SHOW_PANEL, () =>
        {
            return new ShowPanelCommand();
        });

        RegisterCommand(PureNotification.HIDE_PANEL, () =>
        {
            return new HidePanelCommand();
        });
    }

    //4.一定是有一个启动函数的
    public void StartUp()
    {
        //发送通知
        SendNotification(PureNotification.START_UP);

        //SendNotification(PureNotification.SHOW_PANEL, "MainPanel");
    }
}

Main

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Main : MonoBehaviour
{
    void Start()
    {
        GameFacade.Instance.StartUp();   
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.M))
        {
            //显示主面板
            GameFacade.Instance.SendNotification(PureNotification.SHOW_PANEL, "MainPanel");
        }
        else if (Input.GetKeyDown(KeyCode.N))
        {
            //隐藏主面板
            GameFacade.Instance.SendNotification(PureNotification.HIDE_PANEL, GameFacade.Instance.RetrieveMediator(NewMainViewMediator.NAME));
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏