网站付费推广有哪些,利用渗透的网站做寄生虫,福田公司是国企吗,一般给公司做网站怎么收费概述
1.最外层DataForm为空壳编辑数据用。可以有多个DataForm#xff0c;例如福利DataForm#xff0c;抽奖DataForm 2.Menu层为左边栏层#xff0c;每个DataForm可以使用不同样式的MenuForm预制体 3.DataForm中使用ReorderList#xff0c;可排列配置 4.有定位功能#xf…概述
1.最外层DataForm为空壳编辑数据用。可以有多个DataForm例如福利DataForm抽奖DataForm 2.Menu层为左边栏层每个DataForm可以使用不同样式的MenuForm预制体 3.DataForm中使用ReorderList可排列配置 4.有定位功能跳转到对应页签 5.DataForm具有树状图管理1级2级菜单 6.PageForm为每个页签的具体生命周期脚本由DataForm控制。需要显示时如果没加载过从资源加载。
TabViewDataForm
树状图数据
每个主UI使用共用的脚本用于编辑左边页签数据结构。主UI即分配ID可以通过UI管理器加载出来。例如福利主UI其中包含多个子页签 树状图菜单分为3种1级无展开1级带展开2级 树状图数据 public ListTabView m_listItem new ListTabView(4);/// summary/// 面板上编辑TreeView数据包含1级2级/// /summary[System.Serializable]public class TabView{public TabViewItem m_item;//1级public ListTabViewItem m_listSubItem null; //2级列表}//每个菜单的data[System.Serializable]public class TabViewItem{public string m_name; //无用字段public string m_assetPath; //资源路径从Assets/开始public string m_dicKey; //字典key用于多语言public string m_chName; //中文注释名程序不用策划可以面板上看排列}使用ReorderableList自定义面板编辑
生成TabView枚举
从外部需要跳转到主UI树状图的某个菜单给1级2级菜单分配唯一id 规则为枚举名为预制体名TabViewForm 枚举里每项为这个页签的assetPath路径中的预制体名。例如assetPath 为 Assets/TestTabView0_0.prefab那么名字为TestTabView0_0 值每个页签first * 1000 second。 每次如果UI预制体修改了树状图顺序重新生成一遍TabView枚举 public enum TestTabViewMainFormTabViewEnum {TestTabView0_0 0,TestTabView0_1 1,TestTabView1_0 1000,TestTabView1_1 1001,TestTabView2 2000,}加载TabViewMenuForm
主UI即绑定TabViewDataForm的空格UI实例化OnInit加载TabViewMenuForm预制体 protected override void OnInit(object userData){//实例化创建MenuFormStarForce.GameEntry.Resource.LoadAsset(m_menuFormAssetPath, m_LoadResourceCallbacks);}加载完毕设置跳转参数到MenuForm中private void LoadAssetSuccessCallback(string AssetName, object asset, float duration, object userData){if (AssetName m_menuFormAssetPath){m_menu inObj.GetComponentTabViewMenuForm();m_menu.SetInfo(this, m_openFistIdx, m_openSecondIdx);m_assetMenu obj;//保存Menu预制体加载在内存中的asset用于UI销毁时引用-1}打开第几菜单并传递参数
主UI打开时传入参数 //打开TabView可定位第几个public class TabViewOpenData{public int m_idx; //打开第几个 first * 位数 secondpublic object m_param; //额外参数传递给page}TabViewOpenData openData new TabViewOpenData();
openData.m_idx (int)TestTabViewMainFormTabViewEnum.TestTabView1_1;
openData.m_param 1234;
StarForce.GameEntry.UI.OpenUIFormById((int)UIFormId.TestTabViewMainForm, openData);在主UI打开时 如果MenuForm加载过调入传入参数idx确定打开第几个 如果MenuForm未加载过保存参数等加载完成回调后打开第几个 protected override void OnOpen(object userData){base.OnOpen(userData);DataInit();if (userData ! null){UIFormParams openUserData userData as UIFormParams;if (openUserData.UserData ! null){m_openData openUserData.UserData as TabViewOpenData;GetFirstSecondByIdx(m_openData.m_idx, out m_openFistIdx, out m_openSecondIdx);if (m_menu ! null){//已经加载成功过menu直接用。否则等加载结束调用m_menu.Select(m_openFistIdx, m_openSecondIdx);}}else{//没有传入参数默认打开第0个m_openFistIdx 0;m_openSecondIdx 0;if (m_menu ! null){//已经加载成功过menu直接用。否则等加载结束调用m_menu.Select(m_openFistIdx, m_openSecondIdx);}}}切换Page
树状菜单点击时或者传入参数打开时 如果跟上次点击idx不一致把上Page置为false判断idx的page是否存在存在即置为true不存在即等待加载 public void OnClickMenu(int first,int second){PublicFunc.Log($点击菜单{first}-{second});int key GetIdxByFirstSecond(first, second);if (key ! m_lastClickIdx){SetPageActive(m_lastClickIdx, false);if (SetPageActive(key, true) false){//操作当前页打开失败说明未加载Page,执行加载逻辑TabViewItem tabViewItem GetDataByFirstSecond(first, second);m_nameSetActiveAfterLoad tabViewItem.m_assetPath; //这个每次点都只会让最新的SetActive trueTabViewPage tabViewPage new TabViewPage();tabViewPage.m_firstIdx first;tabViewPage.m_secondIdx second;tabViewPage.m_data tabViewItem;StarForce.GameEntry.Resource.LoadAsset(tabViewItem.m_assetPath, m_LoadResourceCallbacks, tabViewPage);}m_lastClickIdx key;}//只要点击过menu一次不管是主动点还是传递参数点。open参数都需要无效m_openData null;}销毁时所有asset引用-1
这里不是直接把ab加载出来的asset卸载而是把asset的引用-1然后为0的asset会放入待回收池等待回收池容量满时卸载未使用的ab即ab所有加载出来的asset引用 0 protected override void OnDestroy(){base.OnDestroy();//已经加载过的page的asset 进行asset引用-1foreach (var item in m_dicPage){if (item.Value.m_asset ! null){StarForce.GameEntry.Resource.UnloadAsset(item.Value.m_asset);}}//Menu.asset 引用 - 1如果别的UI还复用此Menu如果引用不为0不会卸载Menu.bundleif (m_assetMenu ! null){StarForce.GameEntry.Resource.UnloadAsset(m_assetMenu);}m_LoadResourceCallbacks null;}TabViewMenuForm
所有界面可复用几个MenuFormMenu具有不同的样式即UI图片不同。注意不可使用TabViewMenuForm的OnEnableOnDisable因为生命周期是跟随主UI的因为主UI的OnOpenOnClose中去调用MenuForm
创建Menu
Menu分为3种1级无展开1级带展开2级 滚动层使用自动布局
FirstMenu使用布局高度
SecondMenu使用布局高度
加载时按照索引加载 void CreateAllMenu(){for (int i 0; i m_dataForm.m_listItem.Count; i){GameObject first GameObject.Instantiate(m_objFirstMenu, m_transContent);TabViewMenuItem item first.GetComponentTabViewMenuItem();item.m_firstIdx i;item.m_secondIdx 0;first.SetActive(true);TabViewItem firstData m_dataForm.m_listItem[i].m_item;item.SetData(firstData);item.m_isExpend false;item.m_isSelect false;m_dicUIFirstMenu.Add(item.m_firstIdx, item);int childCount 0;if (m_dataForm.m_listItem[i].m_listSubItem ! null){ListTabViewMenuItem listSub new ListTabViewMenuItem(4);m_dicUISecondMenu.Add(item.m_firstIdx, listSub);childCount m_dataForm.m_listItem[i].m_listSubItem.Count;for (int secondIdx 0; secondIdx m_dataForm.m_listItem[i].m_listSubItem.Count; secondIdx){GameObject second GameObject.Instantiate(m_objSecondMenu, m_transContent);并把1级有展开与无展开2级记录到字典中 public Dictionaryint, TabViewMenuItem m_dicUIFirstMenu new Dictionaryint, TabViewMenuItem(8); //1级字典public Dictionaryint, ListTabViewMenuItem m_dicUISecondMenu new Dictionaryint, ListTabViewMenuItem(8); //2级跳转定位 public void Select(int firstIdx 0, int secondIdx 0){//全部1级收缩ui恢复为默认状态InitFirstUI();//新的first 打开TabViewMenuItem newFirst;if (m_dicUIFirstMenu.TryGetValue(firstIdx, out newFirst)){ExpendSecond(firstIdx, true);newFirst.SetExpend(true);newFirst.SetSelect(true);}//如果存在2级选中SelectSecond(firstIdx, secondIdx, true);m_dataForm.OnClickMenu(firstIdx, secondIdx);JumpTo(firstIdx);m_lastFirstMenu firstIdx;m_lastSecondMenu secondIdx;}树状图滚动层作为相应处理把fist置为可视区第一行 1.如果contentHeight 可视区height不处理 2.如果需要定位的menu在最后面只需要contentHeight - 可视区height 即为content需要上拉的高度 //跳转到第几项public void JumpTo(int firstIdx){float cotentHeight m_transContent.GetComponentRectTransform().rect.height;float diffY m_firstMenuHeight * firstIdx;Vector3 oldPos Vector3.zero;if (cotentHeight m_viewHeight){diffY 0;}else if (m_viewHeight - (cotentHeight - diffY) 0){//最后一行超过了diffY cotentHeight - m_viewHeight;}oldPos.y diffY;m_transContent.localPosition oldPos;点击处理
1.点击第一级无展开即向主UI传递加载/显示Page 2.点击第一级展开作为展开收缩处理。如果展开判断每次主UI打开有没选择过该First下的某个没有选中Second 0的向主UI传递。如果选择过选择上次选中的second向主UI传递 3.点击2级向主UI传递
TabViewPageForm
所有的page继承于此。作用 1.用于控制生命周期跟Menu一样不能使用OnEnableOnDisable会导致数据有问题即主UI被覆盖然后关闭别的UI恢复主UI不该初始化时初始化了数据 2.传递到主UI的参数最终传递到Page public class TabViewPageForm : MonoBehaviour{public virtual void OnInit(object userData null){}public virtual void OnOpen(object userData null){}继承PageForm的类示例 public class TestTabViewPageForm : TabViewPageForm{public UnityEngine.UI.Text m_text;public override void OnInit(object userData null){}public override void OnOpen(object userData null){if (userData ! null){string param userData as string;m_text.text param;PublicFunc.Log($传入参数{param});}}在TabViewDataForm中如果打开主UI第一次跳转page在加载/显示时会传递参数
if (m_openData ! null)
{if (m_openData.m_idx idx){page.OnInit(m_openData.m_param);page.OnOpen(m_openData.m_param);m_openData null;}else{page.OnInit();page.OnOpen();}
}流程图 效果演示
跳转1_1并传入参数1234
TabViewOpenData openData new TabViewOpenData();
openData.m_idx (int)TestTabViewMainFormTabViewEnum.TestTabView1_1;
openData.m_param 1234;
StarForce.GameEntry.UI.OpenUIFormById((int)UIFormId.TestTabViewMainForm, openData);点击不同页签切换PageView