UGUI之布局的使用


unity的LayoutGroup分為三種,

Horizontal Layout Group(水平布局):對象填充總個父物體,水平會填充

Vertical Layout Group(垂直布局):垂直(高度)會填充

Grid Layout Group (網格布局):以表格的形式布局,不會填充父物體

 比如:垂直布局和水平布局效果

 

Grid Layout Group

  如果單純的時候用滑動效果可以使用Scroll Rect組件即可。但使用布局就要使用布局控件

Grid Layout Group是網格布局,先看看一個效果

其實滑動依然是用的Scroll Rect。這個就不說了。這里主要說布局。

Spacing 表示 cell之間的距離。

Cell表示格子的寬度和和高度

Start Axis 表示布局方式,有橫向和縱向


Child Alignment 表示對齊方式。

 

注意Layout Group節點下面的所有cell節點都是不能修改Rect Transform的。因為cell可能下面會放很多圖片,這樣我們會用個空的gameObject來當父節點。

 

 

 

但你仔細看。會發現。這個不是整塊滑動的。比如手機屏幕左右滑動,是滑動區域判斷的。沒有划過來的時候。會退回去。像這樣

 

這里可以根據Scroll Rect組件的normalizedPosition屬性來判斷。這是一個Vector2坐標。是滑動中XY的值

horizontalNormalizedPosition:水平的值

verticalNormalizedPosition:垂直的值

需要在拖動結束后判斷。需要繼承

IBeginDragHandler,IEndDragHandler。引用命名空間:using UnityEngine.EventSystems;

具體代碼:

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class newScroll : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
    ScrollRect rect;

    //頁面:0,1,2  索引從0開始
    //每夜占的比列:0/2=0  1/2=0.5  2/2=1
    float[] page = { 0, 0.5f, 1 };

    //滑動速度
    public float smooting = 4;

    //滑動的起始坐標
    float targethorizontal = 0;

    //是否拖拽結束
    bool isDrag = false;

    // Use this for initialization
    void Start()
    {
        rect = transform.GetComponent<ScrollRect>();
    }

    // Update is called once per frame
    void Update()
    {
        //如果不判斷。當在拖拽的時候要也會執行插值,所以會出現閃爍的效果
        //這里只要在拖動結束的時候。在進行插值
        if (!isDrag)
        {
            rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, targethorizontal, Time.deltaTime * smooting);
        }
    }

    /// <summary>
    /// 拖動開始
    /// </summary>
    /// <param name="eventData"></param>
    public void OnBeginDrag(PointerEventData eventData)
    {
        isDrag = true;
    }

    /// <summary>
    /// 拖拽結束
    /// </summary>
    /// <param name="eventData"></param>
    public void OnEndDrag(PointerEventData eventData)
    {
        isDrag = false;

        //    //拖動停止滑動的坐標 
        //    Vector2 f = rect.normalizedPosition;
        //    //水平  開始值是0  結尾值是1  [0,1]
        //    float h = rect.horizontalNormalizedPosition;
        //    //垂直
        //    float v = rect.verticalNormalizedPosition;




        float posX = rect.horizontalNormalizedPosition;
        int index = 0;
        //假設離第一位最近
        float offset = Mathf.Abs(page[index] - posX);
        for (int i = 1; i < page.Length; i++)
        {
            float temp = Mathf.Abs(page[i] - posX);
            if (temp < offset)
            {
                index = i;

                //保存當前的偏移量
                //如果到最后一頁。反翻頁。所以要保存該值,如果不保存。你試試效果就知道
                offset = temp;
            }
        }

        /*
         因為這樣效果不好。沒有滑動效果。比較死板。所以改為插值
         */
        //rect.horizontalNormalizedPosition = page[index];


        targethorizontal = page[index];
    }
}

 

像這種布局。內容是動態添加的。所以內容的多少是不確定的。很多時候是用u3d自帶的ContentSizeFitter。這個組件可以自動計算寬度

 

那么問題來了。當總數不是頁數的倍數,那么horizontalNormalizedPosition是不正確的。比如:有2頁。一頁5條

當只有6條。是不是也是2頁呢?。

所以又得必須動態計算了。

這里寫了一個適用於其他場合的類

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using UnityEngine;
  6 using UnityEngine.EventSystems;
  7 using UnityEngine.UI;
  8 
  9 class UIScrollItemTips : MonoBehaviour, IBeginDragHandler, IEndDragHandler
 10 {
 11     //頁面:0,1,2  索引從0開始
 12     //每夜占的比列:0/2=0  1/2=0.5  2/2=1
 13     public List<float> pageArray;
 14 
 15     //public List<float> PageArray
 16     //{
 17     //    // get { return pageArray; }
 18     //    set { pageArray = value; }
 19     //}
 20     private List<Toggle> toggleArray;
 21 
 22     public List<Toggle> ToggleArray
 23     {
 24         //get { return toggleArray; }
 25         set { toggleArray = value; }
 26     }
 27     public int pageCount;//多少頁
 28 
 29     public int pageIndex = 0;//:當前頁碼
 30     private ScrollRect rect;
 31     //滑動速度
 32     public float smooting;
 33 
 34     public float Smooting
 35     {
 36         get { return smooting; }
 37         set { smooting = value; }
 38     }
 39 
 40     private int pageSize;
 41 
 42     /// <summary>
 43     /// 一頁顯示多少條
 44     /// </summary>
 45     public int setPageSize
 46     {
 47         get { return pageSize; }
 48         set { pageSize = value; }
 49     }
 50 
 51     private int sumRecord;
 52 
 53     /// <summary>
 54     /// 總記錄數
 55     /// </summary>
 56     public int setSumRecord
 57     {
 58         get { return sumRecord; }
 59         set { sumRecord = value; }
 60     }
 61 
 62     private List<GameObject> pageList = new List<GameObject>();
 63 
 64     //滑動的起始坐標
 65     public float targethorizontal = 0;
 66 
 67     //是否拖拽結束
 68     public bool isDrag = false;
 69 
 70 
 71     public GameObject root;
 72 
 73     private int updateInfo;
 74 
 75     public int UpdateInfo
 76     {
 77         //get { return updateInof; }
 78         set { Init(); }
 79     }
 80 
 81     //private static UIScrollItem instance;
 82     //public static UIScrollItem Instance
 83     //{
 84     //    get { return instance; }
 85     //    //set { ObjectPools.instance = value; }
 86     //}
 87 
 88     void Init()
 89     {
 90         UnInit();
 91         //pageSize = 8;
 92         //setSumRecord = 54;
 93         smooting = 4;
 94         rect = transform.GetComponent<ScrollRect>();
 95         pageArray = new List<float>();
 96         toggleArray = new List<Toggle>();
 97         targethorizontal = 0;
 98         rect.horizontalNormalizedPosition = 0;
 99         //instance = this; //單列
100 
101         pageCount = Convert.ToInt32(Math.Ceiling((double)sumRecord / pageSize)); //sumRecord為總記錄數
102 
103         //Debug.LogError(pageCount);
104 
105         //求出每頁的臨界角,頁索引從0開始
106         int num = pageCount - 1;
107         if (num == 0) num = 1;
108         for (int i = 0; i < pageCount; i++)
109         {
110             //Debug.LogError(i + "/" + num + "==" + (float)i / (float)num);
111             pageArray.Add((float)i / (float)num);
112         }
113 
114         if (root != null)
115         {
116             ToggleGroup group = root.GetComponent<ToggleGroup>();
117 
118             for (int i = 0; i < pageCount; i++)
119             {
120                 //獲取頁碼預設體
121                 GameObject pageItem = U3DResources.SpawnUI("Item_New");
122                 pageList.Add(pageItem);
123                 pageItem.transform.SetParent(root.transform);
124                 pageItem.transform.localScale = new Vector3(1, 1, 1);
125                 pageItem.transform.localRotation = new Quaternion();
126                 pageItem.transform.localPosition = Vector3.one;
127 
128                 Toggle toogle = pageItem.transform.Find("page").GetComponent<Toggle>();
129                 toogle.group = group;
130                 toggleArray.Add(toogle);
131             }
132 
133 
134         }
135 
136         //Debug.LogError(pageSize);
137 
138         //rect.horizontalNormalizedPosition = 0;
139 
140         //不管怎樣默認都是顯示最后一頁,同理,頁碼頁碼也是。已在生成頁碼時處理
141         //初始化不需要顯示滑動效果。直接賦值即可
142         //targethorizontal = pageArray[pageArray.Count - 1];
143         //rect.horizontalNormalizedPosition = pageArray[pageArray.Count - 1];
144 
145         foreach (var item in toggleArray)
146         {
147             item.isOn = false;
148         }
149 
150         if (toggleArray.Count > 0)
151         {
152             //默認第一個選中
153             toggleArray[0].isOn = true;
154 
155         }
156     }
157 
158     void Awake()
159     {
160     }
161     void Start()
162     {
163         //Init();
164         //rect.horizontalNormalizedPosition = 0;
165     }
166 
167     void Update()
168     {
169         //如果不判斷。當在拖拽的時候要也會執行插值,所以會出現閃爍的效果
170         ////這里只要在拖動結束的時候。在進行插值
171         if (!isDrag)
172         {
173             rect.horizontalNormalizedPosition = Mathf.Lerp(rect.horizontalNormalizedPosition, targethorizontal, Time.deltaTime * smooting);
174 
175             //rect.horizontalNormalizedPosition = targethorizontal;
176         }
177     }
178     /// <summary>
179     /// 拖動開始
180     /// </summary>
181     /// <param name="eventData"></param>
182     public void OnBeginDrag(PointerEventData eventData)
183     {
184         isDrag = true;
185     }
186 
187     /// <summary>
188     /// 拖拽結束
189     /// </summary>
190     /// <param name="eventData"></param>
191     public void OnEndDrag(PointerEventData eventData)
192     {
193         isDrag = false;
194 
195         float posX = rect.horizontalNormalizedPosition;
196         int index = 0;
197         //假設離第一位最近
198         float offset = Mathf.Abs(pageArray[index] - posX);
199         for (int i = 1; i < pageArray.Count; i++)
200         {
201             float temp = Mathf.Abs(pageArray[i] - posX);
202             if (temp < offset)
203             {
204                 index = i;
205                 //保存當前的偏移量
206                 offset = temp;
207             }
208         }
209         try
210         {
211             targethorizontal = pageArray[index];
212             //說明頁碼大於1 toggle有值
213             if (pageCount > 1 && toggleArray.Count > 0)
214                 toggleArray[index].isOn = true;
215         }
216         catch (Exception)
217         {
218             return;
219         }
220     }
221 
222     void UnInit()
223     {
224         foreach (var item in pageList)
225         {
226             U3DResources.Despawn(item);
227         }
228     }
229 }
View Code

調用

 1 itemTips.setSumRecord = nows;
 2             itemTips.setPageSize = 8;
 3             mItemGrid.GetComponent<ContentSizeFitter>().enabled = false;
 4 
 5             //總頁數
 6             int pageCount = Convert.ToInt32(Math.Ceiling((double)nows / itemTips.setPageSize)); //sumRecord為總記錄數
 7 
 8             int resultCount = nows;
 9 
10             if (nows % itemTips.setPageSize != 0)
11             {
12                 //求差
13                 int poor = pageCount * itemTips.setPageSize - nows;
14                 //加上差數。湊整
15                 resultCount = nows + poor;
16             }
17             else
18             {
19                 //可以啟用自動計算寬度
20                 //mItemGrid.GetComponent<ContentSizeFitter>().enabled = true;
21             }
22 
23             //Debug.LogError(nows);
24             //Debug.LogError(resultCount);
25 
26             GridLayoutGroup group = mItemGrid.GetComponent<GridLayoutGroup>();
27             float cellSize = group.cellSize.x; //一個格子的寬度
28             float spacing = group.spacing.x; //格子的間距
29 
30             //總寬度
31             float totalWidth = cellSize * resultCount + (resultCount - 1) * spacing;
32             //Debug.LogError(totalWidth);
33 
34             RectTransform rectWidth = mItemGrid.GetComponent<RectTransform>();
35             Vector2 targetVec = new Vector2(totalWidth, rectWidth.sizeDelta.y);
36             rectWidth.sizeDelta = targetVec;
View Code

itemTips是UIScrollItemTips變量

ScrollRect滑動組件。怎么可以定位到哪個地方呢。即滑動到指定位置;

ScrollRect有個屬性normalizedPosition,是Vector2類型的。

如果是垂直滑動;那么范圍是1-0

比如到初始位置

GetComponent<ScrollRect>().normalizedPosition = new Vector2(0, 1);

滑動到最后一頁

GetComponent<ScrollRect>().normalizedPosition = new Vector2(0, 0);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM