UGUI動態生成列表功能實現(增刪保存)

在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的尺寸調整成你要的尺寸就能夠了。

相關文章
相關標籤/搜索