在UGUI 裏難免會有一些列表須要生成和顯示。例如最簡單的增、刪、改、查等都須要列表的變化。本文只講增、刪、保存、清空UGUI配合的變化方法。ide
下面以實現場景裏角色的實時位置的增長、刪除、保存爲案例開講。post
先看一下實現增長效果圖:this
首先是UI的製做,這個比較簡單,以前講過的,能夠參考:http://blog.csdn.net/alayeshi/article/details/50240075spa
下面圖片是整個列表的核心--grid和其子物體,grid就是生成全部子物體的父物體,而這些子物體就是新生成的列表裏的每一行,在grid上規定好子物體的寬度和高度,而後加上Generaterecord腳本。.net
下面實現增長功能:設計
點擊按鈕增長一個grid的子物體,也就是新增長列表裏的一行。gridlayoutgroup 是會自動排布好你增長出來的子物體。因此咱們只須要寫增長物體的代碼就好。rest
而增長的方法其實就是在整個代碼裏的生成子物體的方法Generategrids()。在這個方法裏不要忘記每增長一個gird的子物體都要將gird的高度增長,因此有了這句代碼:code
this.gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(this.gameObject.GetComponent<RectTransform>().sizeDelta.x, this.gameObject.GetComponent<RectTransform>().sizeDelta.y + this.GetComponent<GridLayoutGroup>().cellSize.y + this.GetComponent<GridLayoutGroup>().spacing.y);
刪除的操做:orm
由於刪除是多選刪除,每次刪除列表裏的個數不肯定,全部咱們要給一個標記,所以會看到下圖中會有一個toggle。若是Toggle是被選中的狀態而且點擊了刪除按鈕那麼列表裏全部被選中的行都會被刪除。在代碼裏須要一個list來保存全部被添加進來的子物體們,在刪除時要遍歷他們,而後根據toggle的狀態決定這些子物體中那些要被刪除,刪除要destroy被選中的物體,還要把list裏的對應的移除掉,以及把grid的高度改變。整個方法在代碼裏是Destroyselfs()整個方法。對象
下面實現保存的方法:
保存咱們用unity本身的方法 PlayerPrefs.SetInt();原理很簡單,它裏面的兩個參數分別是一個key,一個value。根據key來判斷value。例如: PlayerPrefs.SetInt("存儲個數", gridlist.Count);若是「存儲個數」整個字符串是存在的那麼就能夠得到gridlist.count整個value。因此咱們在保存的時候要保證key是不一樣的。而後當下次運行時就根據key來判斷,而後加載那些value而且顯示到列表的行中。
具體要看如下代碼:
下面是以上增刪保存的所有的代碼:
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using UnityEngine.UI; 5 6 public class generaterecords : MonoBehaviour 7 { 8 public Button ADD, Delete, Save, Clearsave; 9 private string gridpath; 10 private GameObject gridrecord; 11 12 string positions;//用來解析位置信息 13 Vector3 personpositions;//座標位置 14 15 List<string> postionlist = new List<string>();//保存grid裏面的文字 16 List<string> describepositionlist = new List<string>();//位置前的文字描述 17 18 List<GameObject> gridlist = new List<GameObject>(); //用來存儲grid下的對象 19 GameObject go;//生成的grid子物體 20 21 22 23 string loadpositions;//加載的位置信息 24 string loadstring;//加載位置信息對應的文字 25 // Use this for initialization 26 void Start() 27 { 28 ADD.onClick.AddListener(Addposition); 29 Delete.onClick.AddListener(Deletposition); 30 Save.onClick.AddListener(Saveposition); 31 Clearsave.onClick.AddListener(Clearall); 32 33 34 gridpath = "backup/gridcontent"; 35 36 gridrecord = Resources.Load(gridpath, typeof(GameObject)) as GameObject; 37 38 if (gridrecord != null) 39 { 40 Debug.Log(gridrecord.name); 41 } 42 43 //清空位置的list 44 postionlist.Clear(); 45 //清空物體list 46 gridlist.Clear(); 47 ///初始化加載grid物體個數 48 /// 49 if (PlayerPrefs.GetInt("存儲個數", 0) > 0) 50 { 51 Debug.Log("得到到存儲的個數是" + PlayerPrefs.GetInt("存儲個數", 0)); 52 53 //遍歷存儲的個數,並生產grid物體 54 for (int i = 0; i < PlayerPrefs.GetInt("存儲個數", 0); i++) 55 { 56 57 Debug.Log("得到的當前存儲key是" + i); 58 59 //獲取保存的位置數據--以備填充到grids物體裏 60 ///經過key來進行獲取數值,key必定是從0開始的,只要最後小於存儲個數(也就是list.count)一位就OK, 61 ///而該for循環裏的i也是從0開始的因此正好 62 63 if (i < PlayerPrefs.GetInt("存儲個數", 0)) 64 { 65 loadpositions = PlayerPrefs.GetString(i.ToString(), "沒有該key呀"); 66 Debug.Log("獲取的內容;" + loadpositions); 67 postionlist.Add(loadpositions); 68 69 loadstring = PlayerPrefs.GetString(i.ToString() + "describe", "描述位置的文字"); 70 describepositionlist.Add(loadstring); 71 } 72 73 //生成grids物體 74 Generategrids(); 75 76 } 77 } 78 else 79 { 80 Debug.Log("存儲次數居然爲" + PlayerPrefs.GetInt("存儲次數", 0)); 81 } 82 83 } 84 //添加方法 85 void Addposition() 86 { 87 //主角位置信息獲取 88 personpositions = GameObject.Find("FPSControllermine").transform.position; 89 positions = personpositions.ToString(); 90 Debug.Log("主角位置:" + positions); 91 92 Generategrids(); 93 94 //生成文字位置 95 Generateposition(); 96 } 97 98 //delet方法 99 void Deletposition() 100 { 101 Destroyselfs(); 102 } 103 ////保存的方法 104 void Saveposition() 105 { 106 Debug.Log("描述文字:8888"); 107 if (gridlist.Count > 0) 108 { 109 for (int i = 0; i < gridlist.Count; i++) 110 { 111 Debug.Log("描述文字:qqq"); 112 //存的描述的文字不能是空和「」 113 if (gridlist[i].transform.FindChild("InputField/Text").GetComponent<Text>().text != "") 114 115 { 116 Debug.Log("描述文字:ssss"); 117 string describetextfor = gridlist[i].transform.FindChild("InputField/Text").GetComponent<Text>().text;//保持描述 118 119 string positionstextfor = gridlist[i].transform.FindChild("positontext").GetComponent<Text>().text;//保存位置 120 deleteclicksaved(i, positionstextfor, describetextfor);//保存方法 121 Debug.Log("描述文字:" + describetextfor); 122 } 123 } 124 125 } 126 } 127 128 /// <summary> 129 /// 清空方法 130 /// </summary> 131 void Clearall() 132 { 133 PlayerPrefs.DeleteAll(); 134 } 135 // Update is called once per frame 136 void Update() 137 { 138 139 140 141 } 142 /// <summary> 143 /// 生成整個gird子物體 144 /// </summary> 145 public void Generategrids() 146 { 147 148 //生成record的物體、 149 go = Instantiate(gridrecord, this.transform.position, Quaternion.identity); 150 go.transform.SetParent(this.transform); 151 152 153 //默認是false,也就是不被選中的 154 go.transform.FindChild("Toggle").GetComponent<Toggle>().isOn = false; 155 156 157 //每個go位置信息顯示(加載過來的文本顯示) 158 if (loadpositions != null) 159 { 160 go.transform.FindChild("positontext").GetComponent<Text>().text = loadpositions;//位置的文字 161 162 163 go.transform.FindChild("InputField/content").gameObject.SetActive(true);//顯示出來不可更改的東西 (描述文字的父物體) 164 165 go.transform.FindChild("InputField/content/changed").GetComponent<Text>().text = loadstring; //描述文字 166 167 } 168 169 gridlist.Add(go); 170 171 Debug.Log("物體個數" + gridlist.Count); 172 173 //本grid長度加go的高度 174 175 this.gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(this.gameObject.GetComponent<RectTransform>().sizeDelta.x, this.gameObject.GetComponent<RectTransform>().sizeDelta.y + this.GetComponent<GridLayoutGroup>().cellSize.y + this.GetComponent<GridLayoutGroup>().spacing.y); 176 Debug.Log("grid的高度" + this.gameObject.GetComponent<RectTransform>().sizeDelta); 177 } 178 179 180 /// <summary> 181 /// 位置獲取,只有新添加位置纔會觸發,從外面加載不走這裏 182 /// </summary> 183 /// 184 private void Generateposition() 185 { 186 187 //位置信息顯示 188 go.transform.FindChild("positontext").GetComponent<Text>().text = positions; 189 190 go.transform.FindChild("InputField/content").gameObject.SetActive(false);//描述文字的父物體不顯示 191 192 193 194 } 195 /// <summary> 196 /// 銷燬被選中的gird子物體 197 /// </summary> 198 /// 199 void Destroyselfs() 200 { 201 202 //由於gridlist的數量會在銷燬期間變,因此把即將銷燬的取出來存放而後銷燬 203 204 //取出被勾選,將銷燬的物體 205 // for (int i = 0; i <gridlist.Count; i++) 206 for (int i = gridlist.Count - 1; i >= 0; i--) 207 { 208 Debug.Log("list裏有" + gridlist.Count + "個gird----" + "第" + i + "個是" + gridlist[i].transform.FindChild("Toggle").GetComponent<Toggle>().isOn); 209 if (gridlist[i].transform.FindChild("Toggle").GetComponent<Toggle>().isOn) 210 { 211 //所謂的key就是該物體當前在list裏所處的位置 212 213 Destroy(gridlist[i]); 214 215 // 將對應裏面的座標list銷燬 216 // postionlist.Remove(postionlist[i]); 217 218 //將物體引用list銷燬 219 gridlist.Remove(gridlist[i]); 220 221 222 //本grid長度減小60 223 this.gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(this.gameObject.GetComponent<RectTransform>().sizeDelta.x, this.gameObject.GetComponent<RectTransform>().sizeDelta.y - this.GetComponent<GridLayoutGroup>().cellSize.y - this.GetComponent<GridLayoutGroup>().spacing.y); 224 225 Debug.Log("刪除後list裏有" + gridlist.Count); 226 227 //將本次刪除完剩下的list遍歷,獲取每一個物體的key,而後保存起來 228 for (int rest = 0; rest < gridlist.Count; rest++) 229 { 230 // if (gridlist[i].transform.FindChild("InputField/changed").GetComponent<Text>().text == "") 231 { 232 string savetext = gridlist[rest].transform.FindChild("positontext").GetComponent<Text>().text; 233 234 string describetext = gridlist[rest].transform.FindChild("InputField/content/changed").GetComponent<Text>().text; //描述文字 235 236 deleteclicksaved(rest, savetext, describetext); 237 238 } 239 240 } 241 242 if (gridlist.Count == 0) 243 { 244 PlayerPrefs.SetInt("存儲個數", gridlist.Count); 245 } 246 247 248 } 249 250 } 251 252 253 } 254 255 256 void deleteclicksaved(int listkey, string saveposi, string described) 257 { 258 PlayerPrefs.SetInt("存儲個數", gridlist.Count); 259 260 //存儲個數就是最後剩下的list裏的個數,比key的最大值大一,由於key是從0開始的 261 Debug.Log("存儲key是" + listkey + "值是" + described); 262 //保存每一個位置 263 PlayerPrefs.SetString(listkey.ToString(), saveposi); 264 265 //保存描述文字 266 PlayerPrefs.SetString(listkey.ToString() + "describe", described); 267 } 268 269 }
注:
在我設計的這個需求裏,保存過的列表再次加載出來是不容許修改的。
實現這個很簡單,在原來輸入框(Inputfield)上又遮擋了一個透明的圖片(此圖名曰:content,默認是不出現這個圖片的由於出現了就沒法點擊輸入了),目的就是爲了當被保存的輸入框再次加載後鼠標點擊沒有反應,又由於是透明的圖片因此依然能夠看到以前你保存的名字。
這就是爲何代碼裏會出現這句代碼: go.transform.FindChild("InputField/content").gameObject.SetActive(false);
以下圖:
這樣全部的功能都實現了。若是你不想看原理,那就是把上面的腳本綁定到grid(你要展現的列表)上再把UI的尺寸調整成你要的尺寸就能夠了。